MB-1192: [feat] Add course ended, not passing certificate status to dashboard messaging (#28405)
* [feat] Add course over, not passing status to dash If a student has not passed a course, the course has ended, and they have a verified seat, we want to show them a message at a glance on the dashboard.
This commit is contained in:
@@ -770,3 +770,16 @@ def does_user_profile_exist(user):
|
||||
return hasattr(user, 'profile')
|
||||
except (ProgrammingError, ObjectDoesNotExist):
|
||||
return False
|
||||
|
||||
|
||||
def user_has_passing_grade_in_course(user, enrollment):
|
||||
"""
|
||||
Check to see if a user has passing grade for a course
|
||||
"""
|
||||
try:
|
||||
course_grade = CourseGradeFactory().read(user, course=enrollment.course_overview, create_if_needed=False)
|
||||
if course_grade:
|
||||
return course_grade.passed
|
||||
except AttributeError:
|
||||
pass
|
||||
return False
|
||||
|
||||
@@ -47,7 +47,12 @@ from openedx.features.enterprise_support.api import (
|
||||
get_enterprise_learner_portal_context,
|
||||
)
|
||||
from common.djangoapps.student.api import COURSE_DASHBOARD_PLUGIN_VIEW_NAME
|
||||
from common.djangoapps.student.helpers import cert_info, check_verify_status_by_course, get_resume_urls_for_enrollments
|
||||
from common.djangoapps.student.helpers import (
|
||||
cert_info,
|
||||
check_verify_status_by_course,
|
||||
get_resume_urls_for_enrollments,
|
||||
user_has_passing_grade_in_course
|
||||
)
|
||||
from common.djangoapps.student.models import (
|
||||
AccountRecovery,
|
||||
CourseEnrollment,
|
||||
@@ -675,10 +680,11 @@ def student_dashboard(request): # lint-amnesty, pylint: disable=too-many-statem
|
||||
# If a course is not included in this dictionary,
|
||||
# there is no verification messaging to display.
|
||||
verify_status_by_course = check_verify_status_by_course(user, course_enrollments)
|
||||
cert_statuses = {
|
||||
enrollment.course_id: cert_info(request.user, enrollment)
|
||||
for enrollment in course_enrollments
|
||||
}
|
||||
cert_statuses = {}
|
||||
passing_courses = {}
|
||||
for enrollment in course_enrollments:
|
||||
cert_statuses[enrollment.course_id] = cert_info(request.user, enrollment)
|
||||
passing_courses[enrollment.course_id] = user_has_passing_grade_in_course(user, enrollment)
|
||||
|
||||
# only show email settings for Mongo course and when bulk email is turned on
|
||||
show_email_settings_for = frozenset(
|
||||
@@ -763,6 +769,7 @@ def student_dashboard(request): # lint-amnesty, pylint: disable=too-many-statem
|
||||
'show_courseware_links_for': show_courseware_links_for,
|
||||
'all_course_modes': course_mode_info,
|
||||
'cert_statuses': cert_statuses,
|
||||
'passing_courses': passing_courses,
|
||||
'credit_statuses': _credit_statuses(user, course_enrollments),
|
||||
'show_email_settings_for': show_email_settings_for,
|
||||
'reverifications': reverifications,
|
||||
|
||||
@@ -340,6 +340,12 @@ class OutlineTabView(RetrieveAPIView):
|
||||
if user_grade:
|
||||
user_has_passing_grade = user_grade.passed
|
||||
|
||||
user_has_passing_grade = False
|
||||
if not request.user.is_anonymous:
|
||||
user_grade = CourseGradeFactory().read(request.user, course)
|
||||
if user_grade:
|
||||
user_has_passing_grade = user_grade.passed
|
||||
|
||||
data = {
|
||||
'access_expiration': access_expiration,
|
||||
'cert_data': cert_data,
|
||||
|
||||
@@ -207,6 +207,7 @@ from common.djangoapps.student.models import CourseEnrollment
|
||||
session_id = enrollment.course_id
|
||||
show_courseware_link = show_courseware_links_for.get(session_id, False)
|
||||
cert_status = cert_statuses.get(session_id)
|
||||
is_passing_course = passing_courses.get(session_id) or False
|
||||
can_refund_entitlement = entitlement and entitlement.is_entitlement_refundable()
|
||||
partner_managed_enrollment = enrollment.mode == 'masters'
|
||||
can_unenroll = False if partner_managed_enrollment else (not cert_status) or cert_status.get('can_unenroll') if not unfulfilled_entitlement else False
|
||||
@@ -220,7 +221,7 @@ from common.djangoapps.student.models import CourseEnrollment
|
||||
show_consent_link = (session_id in consent_required_courses)
|
||||
resume_button_url = resume_button_urls[dashboard_index]
|
||||
%>
|
||||
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_voucher_refundable=is_course_voucher_refundable, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name, resume_button_url=resume_button_url, partner_managed_enrollment=partner_managed_enrollment' />
|
||||
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, is_passing_course=is_passing_course, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_voucher_refundable=is_course_voucher_refundable, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name, resume_button_url=resume_button_url, partner_managed_enrollment=partner_managed_enrollment' />
|
||||
% endfor
|
||||
% if show_load_all_courses_link:
|
||||
<br/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%page expression_filter="h" args="cert_status, course_overview, enrollment, reverify_link" />
|
||||
<%page expression_filter="h" args="cert_status, course_ended_not_passing, course_overview, enrollment, reverify_link" />
|
||||
|
||||
<%!
|
||||
from django.urls import reverse
|
||||
@@ -33,7 +33,10 @@ elif cert_status['status'] == CertificateStatuses.notpassing:
|
||||
else:
|
||||
status_css_class = 'course-status-processing'
|
||||
%>
|
||||
<% requesting_post_url = reverse('generate_user_cert', args=[str(course_overview.id)]) %>
|
||||
<%
|
||||
requesting_post_url = reverse('generate_user_cert', args=[str(course_overview.id)])
|
||||
progress_page_url = reverse('progress', args=[str(course_overview.id)])
|
||||
%>
|
||||
|
||||
% if cert_status['status'] != 'processing':
|
||||
% if cert_status['status'] == 'certificate_earned_but_not_available':
|
||||
@@ -161,5 +164,21 @@ else:
|
||||
|
||||
</div>
|
||||
% endif
|
||||
% elif course_ended_not_passing:
|
||||
<div class="message message-status ${status_css_class} d-flex justify-content-between align-items-center">
|
||||
<div class="message-copy">
|
||||
<%
|
||||
container_string = _("You are not eligible for a certificate.")
|
||||
%>
|
||||
<span class="info-date-block localized-datetime" data-language="${user_language}" data-timezone="${user_timezone}" data-string="${container_string}"></span>
|
||||
</div>
|
||||
<ul class="actions actions-primary">
|
||||
<li class="action">
|
||||
<a class="btn btn-primary" rel="noopener" href="${progress_page_url}" target="_blank" title="${_('This link will open the course progress page' )}">
|
||||
${_("View grades")}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%page args="course_overview, enrollment, entitlement, entitlement_session, course_card_index, is_unfulfilled_entitlement, is_fulfilled_entitlement, entitlement_available_sessions, entitlement_expiration_date, entitlement_expired_at, show_courseware_link, cert_status, can_refund_entitlement, can_unenroll, credit_status, show_email_settings, course_mode_info, is_paid_course, is_course_voucher_refundable, verification_status, course_requirements, dashboard_index, share_settings, related_programs, display_course_modes_on_dashboard, show_consent_link, enterprise_customer_name, resume_button_url, partner_managed_enrollment" expression_filter="h"/>
|
||||
<%page args="course_overview, enrollment, entitlement, entitlement_session, course_card_index, is_unfulfilled_entitlement, is_fulfilled_entitlement, entitlement_available_sessions, entitlement_expiration_date, entitlement_expired_at, show_courseware_link, cert_status, is_passing_course, can_refund_entitlement, can_unenroll, credit_status, show_email_settings, course_mode_info, is_paid_course, is_course_voucher_refundable, verification_status, course_requirements, dashboard_index, share_settings, related_programs, display_course_modes_on_dashboard, show_consent_link, enterprise_customer_name, resume_button_url, partner_managed_enrollment" expression_filter="h"/>
|
||||
|
||||
<%!
|
||||
import datetime
|
||||
@@ -43,6 +43,11 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
is_course_expired = hasattr(show_courseware_link, 'error_code') and show_courseware_link.error_code == 'audit_expired'
|
||||
%>
|
||||
|
||||
<%
|
||||
is_audit_enrollment = enrollment.mode == "audit" or enrollment.mode == "honor"
|
||||
course_ended_not_passing = course_overview.has_ended() and is_passing_course == False and is_audit_enrollment == False
|
||||
%>
|
||||
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
|
||||
<li class="course-item">
|
||||
@@ -350,7 +355,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
|
||||
% endif
|
||||
|
||||
% if cert_status:
|
||||
<%include file='_dashboard_certificate_information.html' args='cert_status=cert_status,course_overview=course_overview, enrollment=enrollment, reverify_link=reverify_link'/>
|
||||
<%include file='_dashboard_certificate_information.html' args='cert_status=cert_status, course_ended_not_passing=course_ended_not_passing, course_overview=course_overview, enrollment=enrollment, reverify_link=reverify_link'/>
|
||||
% endif
|
||||
|
||||
% if credit_status is not None:
|
||||
|
||||
@@ -237,6 +237,7 @@ from common.djangoapps.student.models import CourseEnrollment
|
||||
session_id = enrollment.course_id
|
||||
show_courseware_link = show_courseware_links_for.get(session_id, False)
|
||||
cert_status = cert_statuses.get(session_id)
|
||||
is_passing_course = passing_courses.get(session_id) or False
|
||||
can_refund_entitlement = entitlement and entitlement.is_entitlement_refundable()
|
||||
partner_managed_enrollment = enrollment.mode == 'masters'
|
||||
can_unenroll = False if partner_managed_enrollment else (not cert_status) or cert_status.get('can_unenroll') if not unfulfilled_entitlement else False
|
||||
@@ -251,7 +252,7 @@ from common.djangoapps.student.models import CourseEnrollment
|
||||
course_overview = enrollment.course_overview
|
||||
resume_button_url = resume_button_urls[dashboard_index]
|
||||
%>
|
||||
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_voucher_refundable=is_course_voucher_refundable, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name, resume_button_url=resume_button_url, partner_managed_enrollment=partner_managed_enrollment' />
|
||||
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=course_overview, course_card_index=dashboard_index, enrollment=enrollment, is_unfulfilled_entitlement=is_unfulfilled_entitlement, is_fulfilled_entitlement=is_fulfilled_entitlement, entitlement=entitlement, entitlement_session=entitlement_session, entitlement_available_sessions=entitlement_available_sessions, entitlement_expiration_date=entitlement_expiration_date, entitlement_expired_at=entitlement_expired_at, show_courseware_link=show_courseware_link, cert_status=cert_status, is_passing_course=is_passing_course, can_refund_entitlement=can_refund_entitlement, can_unenroll=can_unenroll, credit_status=credit_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, is_paid_course=is_paid_course, is_course_voucher_refundable=is_course_voucher_refundable, verification_status=course_verification_status, course_requirements=course_requirements, dashboard_index=dashboard_index, share_settings=share_settings, user=user, related_programs=related_programs, display_course_modes_on_dashboard=display_course_modes_on_dashboard, show_consent_link=show_consent_link, enterprise_customer_name=enterprise_customer_name, resume_button_url=resume_button_url, partner_managed_enrollment=partner_managed_enrollment' />
|
||||
% endfor
|
||||
% if show_load_all_courses_link:
|
||||
<br/>
|
||||
|
||||
Reference in New Issue
Block a user