Esempio n. 1
0
def get_certificate_template(course_key, mode):
    """
    Retrieves the custom certificate template based on course_key and mode.
    """
    org_id, template = None, None
    # fetch organization of the course
    course_organization = get_course_organizations(course_key)
    if course_organization:
        org_id = course_organization[0]['id']

    if org_id and mode:
        template = CertificateTemplate.objects.filter(organization_id=org_id,
                                                      course_key=course_key,
                                                      mode=mode,
                                                      is_active=True)
    # if don't template find by org and mode
    if not template and org_id and mode:
        template = CertificateTemplate.objects.filter(organization_id=org_id,
                                                      mode=mode,
                                                      is_active=True)
    # if don't template find by only org
    if not template and org_id:
        template = CertificateTemplate.objects.filter(organization_id=org_id,
                                                      is_active=True)
    # if we still don't template find by only course mode
    if not template and mode:
        template = CertificateTemplate.objects.filter(mode=mode,
                                                      is_active=True)

    return template[0].template if template else None
Esempio n. 2
0
def get_certificate_template(course_key, mode):
    """
    Retrieves the custom certificate template based on course_key and mode.
    """
    org_id, template = None, None
    # fetch organization of the course
    course_organization = get_course_organizations(course_key)
    if course_organization:
        org_id = course_organization[0]["id"]

    if org_id and mode:
        template = CertificateTemplate.objects.filter(
            organization_id=org_id, course_key=course_key, mode=mode, is_active=True
        )
    # if don't template find by org and mode
    if not template and org_id and mode:
        template = CertificateTemplate.objects.filter(
            organization_id=org_id, course_key=CourseKeyField.Empty, mode=mode, is_active=True
        )
    # if don't template find by only org
    if not template and org_id:
        template = CertificateTemplate.objects.filter(
            organization_id=org_id, course_key=CourseKeyField.Empty, mode=None, is_active=True
        )
    # if we still don't template find by only course mode
    if not template and mode:
        template = CertificateTemplate.objects.filter(
            organization_id=None, course_key=CourseKeyField.Empty, mode=mode, is_active=True
        )

    return template[0].template if template else None
    def test_rerun(self):
        """
        Just testing the functionality the view handler adds over the tasks tested in test_clone_course
        """
        add_organization({
            'name': 'Test Organization',
            'short_name': self.source_course_key.org,
            'description': 'Testing Organization Description',
        })
        response = self.client.ajax_post(
            self.course_create_rerun_url, {
                'source_course_key': six.text_type(self.source_course_key),
                'org': self.source_course_key.org,
                'course': self.source_course_key.course,
                'run': 'copy',
                'display_name': 'not the same old name',
            })
        self.assertEqual(response.status_code, 200)
        data = parse_json(response)
        dest_course_key = CourseKey.from_string(data['destination_course_key'])

        self.assertEqual(dest_course_key.run, 'copy')
        source_course = self.store.get_course(self.source_course_key)
        dest_course = self.store.get_course(dest_course_key)
        self.assertEqual(dest_course.start, CourseFields.start.default)
        self.assertEqual(dest_course.end, source_course.end)
        self.assertEqual(dest_course.enrollment_start, None)
        self.assertEqual(dest_course.enrollment_end, None)
        course_orgs = get_course_organizations(dest_course_key)
        self.assertEqual(len(course_orgs), 1)
        self.assertEqual(course_orgs[0]['short_name'],
                         self.source_course_key.org)
Esempio n. 4
0
    def test_rerun(self, pacing_type, expected_self_paced_value, number):
        original_course_run = ToyCourseFactory()
        add_organization({
            'name': 'Test Organization',
            'short_name': original_course_run.id.org,
            'description': 'Testing Organization Description',
        })
        start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
        end = start + datetime.timedelta(days=30)
        user = UserFactory()
        role = 'instructor'
        run = '3T2017'
        url = reverse('api:v1:course_run-rerun',
                      kwargs={'pk': str(original_course_run.id)})
        data = {
            'run': run,
            'schedule': {
                'start': serialize_datetime(start),
                'end': serialize_datetime(end),
            },
            'team': [{
                'user': user.username,
                'role': role,
            }],
            'pacing_type': pacing_type,
        }
        # If number is supplied, this should become the course number used in the course run key
        # If not, it should default to the original course run number that the rerun is based on.
        if number:
            data.update({'number': number})
        response = self.client.post(url, data, format='json')
        assert response.status_code == 201

        course_run_key = CourseKey.from_string(response.data['id'])
        course_run = modulestore().get_course(course_run_key)

        assert course_run.id.run == run
        assert course_run.self_paced is expected_self_paced_value

        if number:
            assert course_run.id.course == number
            assert course_run.id.course != original_course_run.id.course
        else:
            assert course_run.id.course == original_course_run.id.course

        self.assert_course_run_schedule(course_run, start, end)
        self.assert_access_role(course_run, user, role)
        self.assert_course_access_role_count(course_run, 1)
        course_orgs = get_course_organizations(course_run_key)
        self.assertEqual(len(course_orgs), 1)
        self.assertEqual(course_orgs[0]['short_name'],
                         original_course_run.id.org)
 def test_course_creation_without_org_app_enabled(self, store):
     """
     Tests course creation workflow should not create course to org
     link if organizations_app is not enabled.
     """
     with modulestore().default_store(store):
         response = self.client.ajax_post(self.course_create_rerun_url, {
             'org': 'orgX',
             'number': 'CS101',
             'display_name': 'Course with web certs enabled',
             'run': '2015_T2'
         })
         self.assertEqual(response.status_code, 200)
         data = parse_json(response)
         new_course_key = CourseKey.from_string(data['course_key'])
         course_orgs = get_course_organizations(new_course_key)
         self.assertEqual(course_orgs, [])
 def test_course_creation_without_org_app_enabled(self, store):
     """
     Tests course creation workflow should not create course to org
     link if organizations_app is not enabled.
     """
     with modulestore().default_store(store):
         response = self.client.ajax_post(self.course_create_rerun_url, {
             'org': 'orgX',
             'number': 'CS101',
             'display_name': 'Course with web certs enabled',
             'run': '2015_T2'
         })
         self.assertEqual(response.status_code, 200)
         data = parse_json(response)
         new_course_key = CourseKey.from_string(data['course_key'])
         course_orgs = get_course_organizations(new_course_key)
         self.assertEqual(course_orgs, [])
Esempio n. 7
0
def _update_organization_context(context, course):
    """
    Updates context with organization related info.
    """
    partner_long_name, organization_logo = None, None
    partner_short_name = course.display_organization if course.display_organization else course.org
    organizations = organization_api.get_course_organizations(course_id=course.id)
    if organizations:
        #TODO Need to add support for multiple organizations, Currently we are interested in the first one.
        organization = organizations[0]
        partner_long_name = organization.get('name', partner_long_name)
        partner_short_name = organization.get('short_name', partner_short_name)
        organization_logo = organization.get('logo', None)

    context['organization_long_name'] = partner_long_name
    context['organization_short_name'] = partner_short_name
    context['accomplishment_copy_course_org'] = partner_short_name
    context['organization_logo'] = organization_logo
 def test_course_creation_with_org_in_system(self, store):
     """
     Tests course creation workflow when course organization exist in system.
     """
     add_organization({
         'name': 'Test Organization',
         'short_name': 'orgX',
         'description': 'Testing Organization Description',
     })
     with modulestore().default_store(store):
         response = self.client.ajax_post(self.course_create_rerun_url, {
             'org': 'orgX',
             'number': 'CS101',
             'display_name': 'Course with web certs enabled',
             'run': '2015_T2'
         })
         self.assertEqual(response.status_code, 200)
         data = parse_json(response)
         new_course_key = CourseKey.from_string(data['course_key'])
         course_orgs = get_course_organizations(new_course_key)
         self.assertEqual(len(course_orgs), 1)
         self.assertEqual(course_orgs[0]['short_name'], 'orgX')
 def test_course_creation_with_org_in_system(self, store):
     """
     Tests course creation workflow when course organization exist in system.
     """
     add_organization({
         'name': 'Test Organization',
         'short_name': 'orgX',
         'description': 'Testing Organization Description',
     })
     with modulestore().default_store(store):
         response = self.client.ajax_post(self.course_create_rerun_url, {
             'org': 'orgX',
             'number': 'CS101',
             'display_name': 'Course with web certs enabled',
             'run': '2015_T2'
         })
         self.assertEqual(response.status_code, 200)
         data = parse_json(response)
         new_course_key = CourseKey.from_string(data['course_key'])
         course_orgs = get_course_organizations(new_course_key)
         self.assertEqual(len(course_orgs), 1)
         self.assertEqual(course_orgs[0]['short_name'], 'orgX')
Esempio n. 10
0
def get_certificate_template(course_key, mode, language):  # pylint: disable=unused-argument
    """
    Retrieves the custom certificate template based on course_key, mode, and language.
    """
    org_id, template = None, None
    # fetch organization of the course
    course_organization = get_course_organizations(course_key)
    if course_organization:
        org_id = course_organization[0]['id']

    if org_id and mode:
        template = CertificateTemplate.objects.filter(organization_id=org_id,
                                                      course_key=course_key,
                                                      mode=mode,
                                                      is_active=True)
    # if don't template find by org and mode
    if not template and org_id and mode:
        template = CertificateTemplate.objects.filter(
            organization_id=org_id,
            course_key=CourseKeyField.Empty,
            mode=mode,
            is_active=True)
    # if don't template find by only org
    if not template and org_id:
        template = CertificateTemplate.objects.filter(
            organization_id=org_id,
            course_key=CourseKeyField.Empty,
            mode=None,
            is_active=True)
    # if we still don't template find by only course mode
    if not template and mode:
        template = CertificateTemplate.objects.filter(
            organization_id=None,
            course_key=CourseKeyField.Empty,
            mode=mode,
            is_active=True)

    return template[0].template if template else None
Esempio n. 11
0
    def __init__(self,
                 course,
                 user,
                 course_desc,
                 path_builder=None,
                 preview_mode=None):
        self.course_id = course.id

        self.path_builder = path_builder
        self.certificate_data = get_active_web_certificate(
            course, preview_mode)
        self.cert = self._get_user_certificate(user,
                                               course,
                                               preview_mode=preview_mode)
        course_title_from_cert = self.certificate_data.get('course_title')
        self.course_name = course_title_from_cert if course_title_from_cert else course.display_name
        self.course_desc = course_desc
        self.organizations = organization_api.get_course_organizations(
            course_id=self.course_id)
        self.sponsors = None

        self.colors = {
            'base': (225 / 255.0, 0 / 255.0, 67 / 255.0),
            'grey-dark': (66 / 255.0, 74 / 255.0, 82 / 255.0),
            'grey-light': (113 / 255.0, 113 / 255.0, 113 / 255.0),
        }

        self.temp_file = NamedTemporaryFile(suffix='-cert.pdf')
        self.is_english = not contains_rtl_text(self.course_name)
        self.user_profile_name = self._get_user_name(user)

        self.left_panel_center = 1.6
        self.ctx = None
        self.size = None
        self.font = None
        self.font_size = None
Esempio n. 12
0
    def get(self, request, course_id, error=None):
        """Displays the course mode choice page.

        Args:
            request (`Request`): The Django Request object.
            course_id (unicode): The slash-separated course key.

        Keyword Args:
            error (unicode): If provided, display this error message
                on the page.

        Returns:
            Response

        """
        course_key = CourseKey.from_string(course_id)

        # Check whether the user has access to this course
        # based on country access rules.
        embargo_redirect = embargo_api.redirect_if_blocked(
            course_key,
            user=request.user,
            ip_address=get_ip(request),
            url=request.path)
        if embargo_redirect:
            return redirect(embargo_redirect)

        enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
            request.user, course_key)
        modes = CourseMode.modes_for_course_dict(course_key)
        ecommerce_service = EcommerceService()

        # We assume that, if 'professional' is one of the modes, it should be the *only* mode.
        # If there are both modes, default to non-id-professional.
        has_enrolled_professional = (
            CourseMode.is_professional_slug(enrollment_mode) and is_active)
        if CourseMode.has_professional_mode(
                modes) and not has_enrolled_professional:
            purchase_workflow = request.GET.get("purchase_workflow", "single")
            verify_url = reverse('verify_student_start_flow',
                                 kwargs={'course_id': unicode(course_key)})
            redirect_url = "{url}?purchase_workflow={workflow}".format(
                url=verify_url, workflow=purchase_workflow)
            if ecommerce_service.is_enabled(request.user):
                professional_mode = modes.get(
                    CourseMode.NO_ID_PROFESSIONAL_MODE) or modes.get(
                        CourseMode.PROFESSIONAL)
                if purchase_workflow == "single" and professional_mode.sku:
                    redirect_url = ecommerce_service.checkout_page_url(
                        professional_mode.sku)
                if purchase_workflow == "bulk" and professional_mode.bulk_sku:
                    redirect_url = ecommerce_service.checkout_page_url(
                        professional_mode.bulk_sku)
            return redirect(redirect_url)

        # If there isn't a verified mode available, then there's nothing
        # to do on this page.  Send the user to the dashboard.
        if not CourseMode.has_verified_mode(modes):
            return redirect(reverse('dashboard'))

        # If a user has already paid, redirect them to the dashboard.
        if is_active and (enrollment_mode in CourseMode.VERIFIED_MODES +
                          [CourseMode.NO_ID_PROFESSIONAL_MODE]):
            return redirect(reverse('dashboard'))

        donation_for_course = request.session.get("donation_for_course", {})
        chosen_price = donation_for_course.get(unicode(course_key), None)

        course = modulestore().get_course(course_key)
        if CourseEnrollment.is_enrollment_closed(request.user, course):
            locale = to_locale(get_language())
            enrollment_end_date = format_datetime(course.enrollment_end,
                                                  'short',
                                                  locale=locale)
            params = urllib.urlencode({'course_closed': enrollment_end_date})
            return redirect('{0}?{1}'.format(reverse('dashboard'), params))

        # When a credit mode is available, students will be given the option
        # to upgrade from a verified mode to a credit mode at the end of the course.
        # This allows students who have completed photo verification to be eligible
        # for univerity credit.
        # Since credit isn't one of the selectable options on the track selection page,
        # we need to check *all* available course modes in order to determine whether
        # a credit mode is available.  If so, then we show slightly different messaging
        # for the verified track.
        has_credit_upsell = any(
            CourseMode.is_credit_mode(mode)
            for mode in CourseMode.modes_for_course(course_key,
                                                    only_selectable=False))
        course_id = course_key.to_deprecated_string()
        context = {
            "course_modes_choose_url":
            reverse("course_modes_choose", kwargs={'course_id': course_id}),
            "modes":
            modes,
            "has_credit_upsell":
            has_credit_upsell,
            "course_name":
            course.display_name_with_default_escaped,
            "course_org":
            course.display_org_with_default,
            "course_num":
            course.display_number_with_default,
            "chosen_price":
            chosen_price,
            "error":
            error,
            "responsive":
            True,
            "nav_hidden":
            True,
        }

        title_content = _(
            "Congratulations!  You are now enrolled in {course_name}").format(
                course_name=course.display_name_with_default_escaped)
        enterprise_learner_data = enterprise_api.get_enterprise_learner_data(
            site=request.site, user=request.user)
        if enterprise_learner_data:
            is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
                site=request.site,
                course_id=course_id,
                enterprise_catalog_id=enterprise_learner_data[0]
                ['enterprise_customer']['catalog'])

            if is_course_in_enterprise_catalog:
                partner_names = partner_name = course.display_organization \
                    if course.display_organization else course.org
                enterprise_name = enterprise_learner_data[0][
                    'enterprise_customer']['name']
                organizations = organization_api.get_course_organizations(
                    course_id=course.id)
                if organizations:
                    partner_names = ' and '.join([
                        org.get('name', partner_name) for org in organizations
                    ])

                title_content = _(
                    "Welcome, {username}! You are about to enroll in {course_name},"
                    " from {partner_names}, sponsored by {enterprise_name}. Please select your enrollment"
                    " information below.").format(
                        username=request.user.username,
                        course_name=course.display_name_with_default_escaped,
                        partner_names=partner_names,
                        enterprise_name=enterprise_name)
        context["title_content"] = title_content

        if "verified" in modes:
            verified_mode = modes["verified"]
            context["suggested_prices"] = [
                decimal.Decimal(x.strip())
                for x in verified_mode.suggested_prices.split(",")
                if x.strip()
            ]
            context["currency"] = verified_mode.currency.upper()
            context["min_price"] = verified_mode.min_price
            context["verified_name"] = verified_mode.name
            context["verified_description"] = verified_mode.description

            if verified_mode.sku:
                context[
                    "use_ecommerce_payment_flow"] = ecommerce_service.is_enabled(
                        request.user)
                context[
                    "ecommerce_payment_page"] = ecommerce_service.payment_page_url(
                    )
                context["sku"] = verified_mode.sku
                context["bulk_sku"] = verified_mode.bulk_sku

        return render_to_response("course_modes/choose.html", context)
Esempio n. 13
0
def _update_certificate_context(context, course, user, user_certificate):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    user_fullname = user.profile.name
    platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME)
    certificate_type = context.get('certificate_type')
    partner_short_name = course.org
    partner_long_name = None
    organizations = organization_api.get_course_organizations(course_id=course.id)
    if organizations:
        #TODO Need to add support for multiple organizations, Currently we are interested in the first one.
        organization = organizations[0]
        partner_long_name = organization.get('name', partner_long_name)
        partner_short_name = organization.get('short_name', partner_short_name)
        context['organization_long_name'] = partner_long_name
        context['organization_short_name'] = partner_short_name
        context['organization_logo'] = organization.get('logo', None)

    context['username'] = user.username
    context['course_mode'] = user_certificate.mode
    context['accomplishment_user_id'] = user.id
    context['accomplishment_copy_name'] = user_fullname
    context['accomplishment_copy_username'] = user.username
    context['accomplishment_copy_course_org'] = partner_short_name
    context['accomplishment_copy_course_name'] = course.display_name
    context['course_image_url'] = course_image_url(course)
    context['share_settings'] = settings.FEATURES.get('SOCIAL_SHARING_SETTINGS', {})
    context['course_number'] = course.number
    try:
        badge = BadgeAssertion.objects.get(user=user, course_id=course.location.course_key)
    except BadgeAssertion.DoesNotExist:
        badge = None
    context['badge'] = badge

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = "{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix')
    )

    # Translators:  The format of the date includes the full name of the month
    context['certificate_date_issued'] = _('{month} {day}, {year}').format(
        month=user_certificate.modified_date.strftime("%B"),
        day=user_certificate.modified_date.day,
        year=user_certificate.modified_date.year
    )

    if partner_long_name:
        context['accomplishment_copy_course_description'] = _('a course of study offered by {partner_short_name}, an '
                                                              'online learning initiative of {partner_long_name} '
                                                              'through {platform_name}.').format(
            partner_short_name=partner_short_name,
            partner_long_name=partner_long_name,
            platform_name=platform_name
        )
    else:
        context['accomplishment_copy_course_description'] = _('a course of study offered by {partner_short_name}, '
                                                              'through {platform_name}.').format(
            partner_short_name=partner_short_name,
            platform_name=platform_name
        )

    # Translators: Accomplishments describe the awards/certifications obtained by students on this platform
    context['accomplishment_copy_about'] = _('About {platform_name} Accomplishments').format(
        platform_name=platform_name
    )

    context['accomplishment_more_title'] = _("More Information About {user_name}'s Certificate:").format(
        user_name=user_fullname
    )

    # Translators:  This line appears on the page just before the generation date for the certificate
    context['certificate_date_issued_title'] = _("Issued On:")

    # Translators:  The Certificate ID Number is an alphanumeric value unique to each individual certificate
    context['certificate_id_number_title'] = _('Certificate ID Number')

    context['certificate_info_title'] = _('About {platform_name} Certificates').format(
        platform_name=platform_name
    )

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    # 'verifying your identity' refers to the process for establishing the authenticity of the student
    context['certificate_info_description'] = _("{platform_name} acknowledges achievements through certificates, which "
                                                "are awarded for various activities {platform_name} students complete "
                                                "under the <a href='{tos_url}'>{platform_name} Honor Code</a>.  Some "
                                                "certificates require completing additional steps, such as "
                                                "<a href='{verified_cert_url}'> verifying your identity</a>.").format(
        platform_name=platform_name,
        tos_url=context.get('company_tos_url'),
        verified_cert_url=context.get('company_verified_certificate_url')
    )

    context['certificate_verify_title'] = _("How {platform_name} Validates Student Certificates").format(
        platform_name=platform_name
    )

    # Translators:  This text describes the validation mechanism for a certificate file (known as GPG security)
    context['certificate_verify_description'] = _('Certificates issued by {platform_name} are signed by a gpg key so '
                                                  'that they can be validated independently by anyone with the '
                                                  '{platform_name} public key. For independent verification, '
                                                  '{platform_name} uses what is called a '
                                                  '"detached signature"&quot;".').format(platform_name=platform_name)

    context['certificate_verify_urltext'] = _("Validate this certificate for yourself")

    # Translators:  This text describes (at a high level) the mission and charter the edX platform and organization
    context['company_about_description'] = _("{platform_name} offers interactive online classes and MOOCs from the "
                                             "world's best universities, including MIT, Harvard, Berkeley, University "
                                             "of Texas, and many others.  {platform_name} is a non-profit online "
                                             "initiative created by founding partners Harvard and MIT.").format(
        platform_name=platform_name
    )

    context['company_about_title'] = _("About {platform_name}").format(platform_name=platform_name)

    context['company_about_urltext'] = _("Learn more about {platform_name}").format(platform_name=platform_name)

    context['company_courselist_urltext'] = _("Learn with {platform_name}").format(platform_name=platform_name)

    context['company_careers_urltext'] = _("Work at {platform_name}").format(platform_name=platform_name)

    context['company_contact_urltext'] = _("Contact {platform_name}").format(platform_name=platform_name)

    # Translators:  This text appears near the top of the certficate and describes the guarantee provided by edX
    context['document_banner'] = _("{platform_name} acknowledges the following student accomplishment").format(
        platform_name=platform_name
    )

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _('This is a valid {platform_name} certificate for {user_name}, '
                                             'who participated in {partner_short_name} {course_number}').format(
        platform_name=platform_name,
        user_name=user_fullname,
        partner_short_name=partner_short_name,
        course_number=course.number
    )

    # Translators:  This text is bound to the HTML 'title' element of the page and appears in the browser title bar
    context['document_title'] = _("{partner_short_name} {course_number} Certificate | {platform_name}").format(
        partner_short_name=partner_short_name,
        course_number=course.number,
        platform_name=platform_name
    )

    # Translators:  This text fragment appears after the student's name (displayed in a large font) on the certificate
    # screen.  The text describes the accomplishment represented by the certificate information displayed to the user
    context['accomplishment_copy_description_full'] = _("successfully completed, received a passing grade, and was "
                                                        "awarded a {platform_name} {certificate_type} "
                                                        "Certificate of Completion in ").format(
        platform_name=platform_name,
        certificate_type=context.get("certificate_type")
    )

    certificate_type_description = get_certificate_description(user_certificate.mode, certificate_type, platform_name)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # Translators: This line is displayed to a user who has completed a course and achieved a certification
    context['accomplishment_banner_opening'] = _("{fullname}, you've earned a certificate!").format(
        fullname=user_fullname
    )

    # Translators: This line congratulates the user and instructs them to share their accomplishment on social networks
    context['accomplishment_banner_congrats'] = _("Congratulations! This page summarizes all of the details of what "
                                                  "you've accomplished. Show it off to family, friends, and colleagues "
                                                  "in your social and professional networks.")

    # Translators: This line leads the reader to understand more about the certificate that a student has been awarded
    context['accomplishment_copy_more_about'] = _("More about {fullname}'s accomplishment").format(
        fullname=user_fullname
    )
Esempio n. 14
0
    def get(self, request, course_id, error=None):
        """Displays the course mode choice page.

        Args:
            request (`Request`): The Django Request object.
            course_id (unicode): The slash-separated course key.

        Keyword Args:
            error (unicode): If provided, display this error message
                on the page.

        Returns:
            Response

        """
        course_key = CourseKey.from_string(course_id)

        # Check whether the user has access to this course
        # based on country access rules.
        embargo_redirect = embargo_api.redirect_if_blocked(
            course_key,
            user=request.user,
            ip_address=get_ip(request),
            url=request.path
        )
        if embargo_redirect:
            return redirect(embargo_redirect)

        enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(request.user, course_key)
        modes = CourseMode.modes_for_course_dict(course_key)
        ecommerce_service = EcommerceService()

        # We assume that, if 'professional' is one of the modes, it should be the *only* mode.
        # If there are both modes, default to non-id-professional.
        has_enrolled_professional = (CourseMode.is_professional_slug(enrollment_mode) and is_active)
        if CourseMode.has_professional_mode(modes) and not has_enrolled_professional:
            purchase_workflow = request.GET.get("purchase_workflow", "single")
            verify_url = reverse('verify_student_start_flow', kwargs={'course_id': unicode(course_key)})
            redirect_url = "{url}?purchase_workflow={workflow}".format(url=verify_url, workflow=purchase_workflow)
            if ecommerce_service.is_enabled(request.user):
                professional_mode = modes.get(CourseMode.NO_ID_PROFESSIONAL_MODE) or modes.get(CourseMode.PROFESSIONAL)
                if purchase_workflow == "single" and professional_mode.sku:
                    redirect_url = ecommerce_service.get_checkout_page_url(professional_mode.sku)
                if purchase_workflow == "bulk" and professional_mode.bulk_sku:
                    redirect_url = ecommerce_service.get_checkout_page_url(professional_mode.bulk_sku)
            return redirect(redirect_url)

        # If there isn't a verified mode available, then there's nothing
        # to do on this page.  Send the user to the dashboard.
        if not CourseMode.has_verified_mode(modes):
            # If the learner has arrived at this screen via the traditional enrollment workflow,
            # then they should already be enrolled in an audit mode for the course, assuming one has
            # been configured.  However, alternative enrollment workflows have been introduced into the
            # system, such as third-party discovery.  These workflows result in learners arriving
            # directly at this screen, and they will not necessarily be pre-enrolled in the audit mode.
            # In this particular case, Audit is the ONLY option available, and thus we need to ensure
            # that the learner is truly enrolled before we redirect them away to the dashboard.
            if len(modes) == 1 and modes.get(CourseMode.AUDIT):
                CourseEnrollment.enroll(request.user, course_key, CourseMode.AUDIT)
                return redirect(self._get_redirect_url_for_audit_enrollment(request, course_id))
            return redirect(reverse('dashboard'))

        # If a user has already paid, redirect them to the dashboard.
        if is_active and (enrollment_mode in CourseMode.VERIFIED_MODES + [CourseMode.NO_ID_PROFESSIONAL_MODE]):
            return redirect(reverse('dashboard'))

        donation_for_course = request.session.get("donation_for_course", {})
        chosen_price = donation_for_course.get(unicode(course_key), None)

        course = modulestore().get_course(course_key)
        if CourseEnrollment.is_enrollment_closed(request.user, course):
            locale = to_locale(get_language())
            enrollment_end_date = format_datetime(course.enrollment_end, 'short', locale=locale)
            params = urllib.urlencode({'course_closed': enrollment_end_date})
            return redirect('{0}?{1}'.format(reverse('dashboard'), params))

        # When a credit mode is available, students will be given the option
        # to upgrade from a verified mode to a credit mode at the end of the course.
        # This allows students who have completed photo verification to be eligible
        # for univerity credit.
        # Since credit isn't one of the selectable options on the track selection page,
        # we need to check *all* available course modes in order to determine whether
        # a credit mode is available.  If so, then we show slightly different messaging
        # for the verified track.
        has_credit_upsell = any(
            CourseMode.is_credit_mode(mode) for mode
            in CourseMode.modes_for_course(course_key, only_selectable=False)
        )
        course_id = course_key.to_deprecated_string()
        context = {
            "course_modes_choose_url": reverse(
                "course_modes_choose",
                kwargs={'course_id': course_id}
            ),
            "modes": modes,
            "has_credit_upsell": has_credit_upsell,
            "course_name": course.display_name_with_default_escaped,
            "course_org": course.display_org_with_default,
            "course_num": course.display_number_with_default,
            "chosen_price": chosen_price,
            "error": error,
            "responsive": True,
            "nav_hidden": True,
        }

        title_content = _("Congratulations!  You are now enrolled in {course_name}").format(
            course_name=course.display_name_with_default_escaped
        )
        enterprise_learner_data = enterprise_api.get_enterprise_learner_data(site=request.site, user=request.user)
        if enterprise_learner_data:
            enterprise_learner = enterprise_learner_data[0]
            is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
                site=request.site,
                course_id=course_id,
                enterprise_catalog_id=enterprise_learner['enterprise_customer']['catalog']
            )

            if is_course_in_enterprise_catalog:
                partner_names = partner_name = course.display_organization \
                    if course.display_organization else course.org
                enterprise_name = enterprise_learner['enterprise_customer']['name']
                organizations = organization_api.get_course_organizations(course_id=course.id)
                if organizations:
                    partner_names = ' and '.join([org.get('name', partner_name) for org in organizations])

                title_content = _("Welcome, {username}! You are about to enroll in {course_name},"
                                  " from {partner_names}, sponsored by {enterprise_name}. Please select your enrollment"
                                  " information below.").format(
                    username=request.user.username,
                    course_name=course.display_name_with_default_escaped,
                    partner_names=partner_names,
                    enterprise_name=enterprise_name
                )

                # Hide the audit modes for this enterprise customer, if necessary
                if not enterprise_learner['enterprise_customer'].get('enable_audit_enrollment'):
                    for audit_mode in CourseMode.AUDIT_MODES:
                        modes.pop(audit_mode, None)

        context["title_content"] = title_content

        if "verified" in modes:
            verified_mode = modes["verified"]
            context["suggested_prices"] = [
                decimal.Decimal(x.strip())
                for x in verified_mode.suggested_prices.split(",")
                if x.strip()
            ]
            context["currency"] = verified_mode.currency.upper()
            context["min_price"] = verified_mode.min_price
            context["verified_name"] = verified_mode.name
            context["verified_description"] = verified_mode.description

            if verified_mode.sku:
                context["use_ecommerce_payment_flow"] = ecommerce_service.is_enabled(request.user)
                context["ecommerce_payment_page"] = ecommerce_service.payment_page_url()
                context["sku"] = verified_mode.sku
                context["bulk_sku"] = verified_mode.bulk_sku

        return render_to_response("course_modes/choose.html", context)
Esempio n. 15
0
def _update_certificate_context(context, course, user, user_certificate):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    user_fullname = user.profile.name
    platform_name = microsite.get_value("platform_name",
                                        settings.PLATFORM_NAME)
    certificate_type = context.get('certificate_type')
    partner_name = course.org
    organizations = organization_api.get_course_organizations(
        course_id=course.id)
    if organizations:
        #TODO Need to add support for multiple organizations, Currently we are interested in the first one.
        organization = organizations[0]
        partner_name = organization.get('name', course.org)
        context['organization_logo'] = organization.get('logo', None)

    context['username'] = user.username
    context['course_mode'] = user_certificate.mode
    context['accomplishment_user_id'] = user.id
    context['accomplishment_copy_name'] = user_fullname
    context['accomplishment_copy_username'] = user.username
    context['accomplishment_copy_course_org'] = partner_name
    context['accomplishment_copy_course_name'] = course.display_name
    context['course_image_url'] = course_image_url(course)
    context['share_settings'] = settings.FEATURES.get(
        'SOCIAL_SHARING_SETTINGS', {})
    context['course_number'] = course.number
    try:
        badge = BadgeAssertion.objects.get(
            user=user, course_id=course.location.course_key)
    except BadgeAssertion.DoesNotExist:
        badge = None
    context['badge'] = badge

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = "{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix'))

    # Translators:  The format of the date includes the full name of the month
    context['certificate_date_issued'] = _('{month} {day}, {year}').format(
        month=user_certificate.modified_date.strftime("%B"),
        day=user_certificate.modified_date.day,
        year=user_certificate.modified_date.year)

    context['accomplishment_copy_course_description'] = _(
        'a course of study offered by {partner_name}, '
        'through {platform_name}.').format(partner_name=partner_name,
                                           platform_name=platform_name)

    # Translators: Accomplishments describe the awards/certifications obtained by students on this platform
    context['accomplishment_copy_about'] = _(
        'About {platform_name} Accomplishments').format(
            platform_name=platform_name)

    context['accomplishment_more_title'] = _(
        "More Information About {user_name}'s Certificate:").format(
            user_name=user_fullname)

    # Translators:  This line appears on the page just before the generation date for the certificate
    context['certificate_date_issued_title'] = _("Issued On:")

    # Translators:  The Certificate ID Number is an alphanumeric value unique to each individual certificate
    context['certificate_id_number_title'] = _('Certificate ID Number')

    context['certificate_info_title'] = _('About {platform_name} Certificates'
                                          ).format(platform_name=platform_name)

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    # 'verifying your identity' refers to the process for establishing the authenticity of the student
    context['certificate_info_description'] = _(
        "{platform_name} acknowledges achievements through certificates, which "
        "are awarded for various activities {platform_name} students complete "
        "under the <a href='{tos_url}'>{platform_name} Honor Code</a>.  Some "
        "certificates require completing additional steps, such as "
        "<a href='{verified_cert_url}'> verifying your identity</a>.").format(
            platform_name=platform_name,
            tos_url=context.get('company_tos_url'),
            verified_cert_url=context.get('company_verified_certificate_url'))

    context['certificate_verify_title'] = _(
        "How {platform_name} Validates Student Certificates").format(
            platform_name=platform_name)

    # Translators:  This text describes the validation mechanism for a certificate file (known as GPG security)
    context['certificate_verify_description'] = _(
        'Certificates issued by {platform_name} are signed by a gpg key so '
        'that they can be validated independently by anyone with the '
        '{platform_name} public key. For independent verification, '
        '{platform_name} uses what is called a '
        '"detached signature"&quot;".').format(platform_name=platform_name)

    context['certificate_verify_urltext'] = _(
        "Validate this certificate for yourself")

    # Translators:  This text describes (at a high level) the mission and charter the edX platform and organization
    context['company_about_description'] = _(
        "{platform_name} offers interactive online classes and MOOCs from the "
        "world's best universities, including MIT, Harvard, Berkeley, University "
        "of Texas, and many others.  {platform_name} is a non-profit online "
        "initiative created by founding partners Harvard and MIT.").format(
            platform_name=platform_name)

    context['company_about_title'] = _("About {platform_name}").format(
        platform_name=platform_name)

    context['company_about_urltext'] = _(
        "Learn more about {platform_name}").format(platform_name=platform_name)

    context['company_courselist_urltext'] = _(
        "Learn with {platform_name}").format(platform_name=platform_name)

    context['company_careers_urltext'] = _("Work at {platform_name}").format(
        platform_name=platform_name)

    context['company_contact_urltext'] = _("Contact {platform_name}").format(
        platform_name=platform_name)

    # Translators:  This text appears near the top of the certficate and describes the guarantee provided by edX
    context['document_banner'] = _(
        "{platform_name} acknowledges the following student accomplishment"
    ).format(platform_name=platform_name)

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _(
        'This is a valid {platform_name} certificate for {user_name}, '
        'who participated in {partner_name} {course_number}').format(
            platform_name=platform_name,
            user_name=user_fullname,
            partner_name=partner_name,
            course_number=course.number)

    # Translators:  This text is bound to the HTML 'title' element of the page and appears in the browser title bar
    context['document_title'] = _(
        "{partner_name} {course_number} Certificate | {platform_name}").format(
            partner_name=partner_name,
            course_number=course.number,
            platform_name=platform_name)

    # Translators:  This text fragment appears after the student's name (displayed in a large font) on the certificate
    # screen.  The text describes the accomplishment represented by the certificate information displayed to the user
    context['accomplishment_copy_description_full'] = _(
        "successfully completed, received a passing grade, and was "
        "awarded a {platform_name} {certificate_type} "
        "Certificate of Completion in ").format(
            platform_name=platform_name,
            certificate_type=context.get("certificate_type"))

    certificate_type_description = get_certificate_description(
        user_certificate.mode, certificate_type, platform_name)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # Translators: This line is displayed to a user who has completed a course and achieved a certification
    context['accomplishment_banner_opening'] = _(
        "{fullname}, you've earned a certificate!").format(
            fullname=user_fullname)

    # Translators: This line congratulates the user and instructs them to share their accomplishment on social networks
    context['accomplishment_banner_congrats'] = _(
        "Congratulations! This page summarizes all of the details of what "
        "you've accomplished. Show it off to family, friends, and colleagues "
        "in your social and professional networks.")

    # Translators: This line leads the reader to understand more about the certificate that a student has been awarded
    context['accomplishment_copy_more_about'] = _(
        "More about {fullname}'s accomplishment").format(
            fullname=user_fullname)
 def test_get_course_organizations_returns_none_when_app_disabled(self):
     response = organizations_helpers.get_course_organizations(unicode(self.course.id))
     self.assertEqual(len(response), 0)
 def test_get_course_organizations_returns_none_when_app_disabled(self):
     response = organizations_helpers.get_course_organizations(
         unicode(self.course.id))
     self.assertEqual(len(response), 0)