Skip to content
Snippets Groups Projects
Commit 26678daf authored by Albert (AJ) St. Aubin's avatar Albert (AJ) St. Aubin
Browse files

feat: Add the Request Certificate button to a Course card

[MICROBA-678]

When a certificate is in an unexpected state (i.e. notpassing with a
passing grade) this alert will allow the user to attempt to resolve the
issue on their own. It will run the code that checks the certificates
status. It requires that the course is configured to allow users to
Request Certificates though.
parent 6d3a4014
Branches
Tags
No related merge requests found
......@@ -37,6 +37,7 @@ from common.djangoapps.student.models import (
from common.djangoapps.util.password_policy_validators import normalize_password
from lms.djangoapps.certificates.api import (
certificates_viewable_for_course,
cert_generation_enabled,
get_certificate_url,
has_html_certificates_enabled
)
......@@ -46,6 +47,7 @@ from lms.djangoapps.grades.api import CourseGradeFactory
from lms.djangoapps.verify_student.models import VerificationDeadline
from lms.djangoapps.verify_student.services import IDVerificationService
from lms.djangoapps.verify_student.utils import is_verification_expiring_soon, verification_for_datetime
from openedx.core.djangoapps.certificates.api import auto_certificate_generation_enabled
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming.helpers import get_themes
from openedx.core.djangoapps.user_authn.utils import is_safe_login_or_logout_redirect
......@@ -592,6 +594,15 @@ def _cert_info(user, course_overview, cert_status):
)
status_dict['grade'] = str(max_grade)
# If the grade is passing, the status is one of these statuses, and request certificate
# is enabled for a course then we need to provide the option to the learner
if (
status_dict['status'] != CertificateStatuses.downloadable and
(cert_generation_enabled(course_overview.id) or auto_certificate_generation_enabled()) and
persisted_grade.passed
):
status_dict['status'] = CertificateStatuses.requesting
return status_dict
......
$(document).ready(() => {
'use strict';
const requestButtons = document.getElementsByClassName('request-cert');
for (let i = 0; i < requestButtons.length; i++) {
requestButtons[i].addEventListener('click', (event) => {
event.preventDefault();
const endpoint = !!event.target.dataset.endpoint && event.target.dataset.endpoint;
$.ajax({
type: 'POST',
url: endpoint,
dataType: 'text',
success: () => {
location.reload();
},
error: (jqXHR, textStatus, errorThrown) => {
location.reload();
},
});
});
}
});
......@@ -40,6 +40,7 @@ from common.djangoapps.student.models import CourseEnrollment
<%block name="js_extra">
<script src="${static.url('js/commerce/credit.js')}"></script>
<script type="text/javascript" src="${static.url('js/learner_dashboard/certificate_api.js')}"></script>
<%static:js group='dashboard'/>
<script type="text/javascript">
$(document).ready(function() {
......
<%page expression_filter="h" args="cert_status, course_overview, enrollment, reverify_link" />
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML, Text
from common.djangoapps.course_modes.models import CourseMode
......@@ -21,15 +23,16 @@ from lms.djangoapps.certificates.data import CertificateStatuses
<%
if cert_status['status'] == 'certificate_earned_but_not_available':
status_css_class = 'course-status-earned-not-available'
elif cert_status['status'] == 'generating':
elif cert_status['status'] == CertificateStatuses.generating:
status_css_class = 'course-status-certrendering'
elif cert_status['status'] == 'downloadable':
elif cert_status['status'] == CertificateStatuses.downloadable or cert_status['status'] == CertificateStatuses.requesting:
status_css_class = 'course-status-certavailable'
elif cert_status['status'] == 'notpassing':
elif cert_status['status'] == CertificateStatuses.notpassing:
status_css_class = 'course-status-certnotavailable'
else:
status_css_class = 'course-status-processing'
%>
<% requesting_post_url = reverse('generate_user_cert', args=[str(course_overview.id)]) %>
% if cert_status['status'] != 'processing':
% if cert_status['status'] == 'certificate_earned_but_not_available':
......@@ -46,7 +49,7 @@ else:
% else:
<div class="message message-status ${status_css_class} d-flex justify-content-between align-items-center">
<div class="message-copy">
% if cert_status['status'] == CertificateStatuses.downloadable:
% if cert_status['status'] == CertificateStatuses.downloadable or cert_status['status'] == CertificateStatuses.requesting:
${_("Congratulations! Your certificate is ready.")}
% elif cert_status['status'] == 'notpassing':
% if enrollment.mode != 'audit':
......@@ -70,37 +73,43 @@ else:
% endif
</div>
% if cert_status['status'] == 'generating' or cert_status['status'] == 'downloadable' or cert_status['show_survey_button']:
% if cert_status['status'] == CertificateStatuses.generating or cert_status['status'] == CertificateStatuses.downloadable or cert_status['status'] == CertificateStatuses.requesting or cert_status['show_survey_button']:
<div class="wrapper-message-primary">
<ul class="actions actions-primary">
% if cert_status['status'] == 'generating':
% if cert_status['status'] == CertificateStatuses.generating:
<li class="action">
<span class="disabled">
${_("Your {cert_name_short} is Generating").format(cert_name_short=cert_name_short)}
</span>
</li>
% elif cert_status['status'] == 'downloadable' and cert_status.get('show_cert_web_view', False):
% elif cert_status['status'] == CertificateStatuses.requesting:
<li>
<button class="btn btn-primary request-cert" data-endpoint="${requesting_post_url}">
${_('Request Certificate')}
</button>
</li>
% elif cert_status['status'] == CertificateStatuses.downloadable and cert_status.get('show_cert_web_view', False):
<li>
<a class="btn btn-primary" href="${cert_status['cert_web_view_url']}" rel="noopener" target="_blank"
title="${_('This link will open the certificate web view')}">
${_("View my {cert_name_short}").format(cert_name_short=cert_name_short,)}
${_("View my {cert_name_short}").format(cert_name_short=cert_name_short)}
</a>
</li>
% elif cert_status['status'] == 'downloadable' and enrollment.mode in CourseMode.NON_VERIFIED_MODES:
% elif cert_status['status'] == CertificateStatuses.downloadable and enrollment.mode in CourseMode.NON_VERIFIED_MODES:
<li>
<a class="btn btn-primary" href="${cert_status['download_url']}"
title="${_('This link will open/download a PDF document')}">
${_("Download my {cert_name_short}").format(cert_name_short=cert_name_short,)}
</a>
</li>
% elif cert_status['status'] == 'downloadable' and enrollment.mode == 'verified' and cert_status['mode'] == 'honor':
% elif cert_status['status'] == CertificateStatuses.downloadable and enrollment.mode == 'verified' and cert_status['mode'] == 'honor':
<li>
<a class="btn btn-primary" href="${cert_status['download_url']}"
title="${_('This link will open/download a PDF document')}">
${_("Download my {cert_name_short}").format(cert_name_short=cert_name_short)}
</a>
</li>
% elif cert_status['status'] == 'downloadable' and enrollment.mode in CourseMode.VERIFIED_MODES:
% elif cert_status['status'] == CertificateStatuses.downloadable and enrollment.mode in CourseMode.VERIFIED_MODES:
<li>
<a class="btn btn-primary" href="${cert_status['download_url']}"
title="${_('This link will open/download a PDF document of your verified {cert_name_long}.').format(cert_name_long=cert_name_long)}">
......
......@@ -45,6 +45,8 @@ from common.djangoapps.student.models import CourseEnrollment
<%block name="js_extra">
<script src="${static.url('js/commerce/credit.js')}"></script>
<script src="${static.url('js/demographics-collection.js')}"></script>
<script src="${static.url('js/learner_dashboard/certificate_api.js')}"></script>
<%static:js group='dashboard'/>
<script type="text/javascript">
$(document).ready(function() {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment