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
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)
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, [])
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')
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
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
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)
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""".').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 )
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)
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""".').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)