Commit b5910892 by Harry Rein

Display the expired at logic for entitlements on the course dashboard.

LEARNER-3304
parent 47602d7e
...@@ -694,10 +694,11 @@ def dashboard(request): ...@@ -694,10 +694,11 @@ def dashboard(request):
# Get the entitlements for the user and a mapping to all available sessions for that entitlement # Get the entitlements for the user and a mapping to all available sessions for that entitlement
course_entitlements = list(CourseEntitlement.objects.filter(user=user).select_related('enrollment_course_run')) course_entitlements = list(CourseEntitlement.objects.filter(user=user).select_related('enrollment_course_run'))
course_entitlement_available_sessions = { course_entitlement_available_sessions = {}
str(entitlement.uuid): get_course_runs_for_course(str(entitlement.course_uuid)) for course_entitlement in course_entitlements:
for entitlement in course_entitlements course_entitlement.update_expired_at()
} course_entitlement_available_sessions[str(course_entitlement.uuid)] = \
get_course_runs_for_course(str(course_entitlement.course_uuid))
# Record how many courses there are so that we can get a better # Record how many courses there are so that we can get a better
# understanding of usage patterns on prod. # understanding of usage patterns on prod.
......
...@@ -2407,6 +2407,9 @@ SUPPORT_SITE_LINK = '' ...@@ -2407,6 +2407,9 @@ SUPPORT_SITE_LINK = ''
PASSWORD_RESET_SUPPORT_LINK = '' PASSWORD_RESET_SUPPORT_LINK = ''
ACTIVATION_EMAIL_SUPPORT_LINK = '' ACTIVATION_EMAIL_SUPPORT_LINK = ''
# Days before the expired date that we warn the user
ENTITLEMENT_EXPIRED_ALERT_PERIOD = 90
############################# SOCIAL MEDIA SHARING ############################# ############################# SOCIAL MEDIA SHARING #############################
# Social Media Sharing on Student Dashboard # Social Media Sharing on Student Dashboard
SOCIAL_SHARING_SETTINGS = { SOCIAL_SHARING_SETTINGS = {
......
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
availableSessions: [], availableSessions: [],
entitlementUUID: '', entitlementUUID: '',
currentSessionId: '', currentSessionId: '',
courseName: '' courseName: '',
expiredAt: null,
daysUntilExpiration: Number.MAX_VALUE
} }
}); });
} }
......
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
availableSessions: this.formatDates(JSON.parse(options.availableSessions)), availableSessions: this.formatDates(JSON.parse(options.availableSessions)),
entitlementUUID: options.entitlementUUID, entitlementUUID: options.entitlementUUID,
currentSessionId: options.currentSessionId, currentSessionId: options.currentSessionId,
expiredAt: options.expiredAt,
expiresAtDate: this.courseCardModel.formatDate(
new moment().utc().add(options.daysUntilExpiration, 'days')
),
courseName: options.courseName courseName: options.courseName
}); });
this.listenTo(this.entitlementModel, 'change', this.render); this.listenTo(this.entitlementModel, 'change', this.render);
......
...@@ -3,12 +3,18 @@ ...@@ -3,12 +3,18 @@
<%def name="online_help_token()"><% return "learnerdashboard" %></%def> <%def name="online_help_token()"><% return "learnerdashboard" %></%def>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! <%!
import crum
import pytz
import third_party_auth
from courseware.context_processor import user_timezone_locale_prefs
from datetime import datetime, timedelta
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template import RequestContext from django.template import RequestContext
from entitlements.models import CourseEntitlement from entitlements.models import CourseEntitlement
import third_party_auth
from third_party_auth import pipeline from third_party_auth import pipeline
from util.date_utils import strftime_localized
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
...@@ -130,6 +136,10 @@ from student.models import CourseEnrollment ...@@ -130,6 +136,10 @@ from student.models import CourseEnrollment
# Check if the course run is an entitlement and if it has an associated session # Check if the course run is an entitlement and if it has an associated session
entitlement = enrollment if isinstance(enrollment, CourseEntitlement) else None entitlement = enrollment if isinstance(enrollment, CourseEntitlement) else None
entitlement_session = entitlement.enrollment_course_run if entitlement else None entitlement_session = entitlement.enrollment_course_run if entitlement else None
entitlement_days_until_expiration = entitlement.get_days_until_expiration() if entitlement else None
entitlement_expiration = datetime.now(tz=pytz.UTC) + timedelta(days=entitlement_days_until_expiration) if (entitlement and entitlement_days_until_expiration < settings.ENTITLEMENT_EXPIRED_ALERT_PERIOD) else None
entitlement_expiration_date = strftime_localized(entitlement_expiration, 'SHORT_DATE') if entitlement and entitlement_expiration else None
entitlement_expired_at = strftime_localized(entitlement.expired_at_datetime, 'SHORT_DATE') if entitlement and entitlement.expired_at_datetime else None
is_fulfilled_entitlement = True if entitlement and entitlement_session else False is_fulfilled_entitlement = True if entitlement and entitlement_session else False
is_unfulfilled_entitlement = True if entitlement and not entitlement_session else False is_unfulfilled_entitlement = True if entitlement and not entitlement_session else False
...@@ -171,7 +181,7 @@ from student.models import CourseEnrollment ...@@ -171,7 +181,7 @@ from student.models import CourseEnrollment
show_consent_link = (session_id in consent_required_courses) show_consent_link = (session_id in consent_required_courses)
course_overview = enrollment.course_overview course_overview = enrollment.course_overview
%> %>
<%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, show_courseware_link=show_courseware_link, cert_status=cert_status, 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_blocked=is_course_blocked, 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' /> <%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_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_blocked=is_course_blocked, 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' />
% endfor % endfor
</ul> </ul>
......
<%page args="course_overview, enrollment, entitlement, entitlement_session, course_card_index, is_unfulfilled_entitlement, is_fulfilled_entitlement, entitlement_available_sessions, show_courseware_link, cert_status, can_unenroll, credit_status, show_email_settings, course_mode_info, is_paid_course, is_course_blocked, verification_status, course_requirements, dashboard_index, share_settings, related_programs, display_course_modes_on_dashboard, show_consent_link, enterprise_customer_name" 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, can_unenroll, credit_status, show_email_settings, course_mode_info, is_paid_course, is_course_blocked, verification_status, course_requirements, dashboard_index, share_settings, related_programs, display_course_modes_on_dashboard, show_consent_link, enterprise_customer_name" expression_filter="h"/>
<%! <%!
import urllib import urllib
...@@ -131,7 +131,15 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -131,7 +131,15 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
% if is_unfulfilled_entitlement: % if is_unfulfilled_entitlement:
<span class="info-date-block" aria-live="polite"> <span class="info-date-block" aria-live="polite">
<span class="icon fa fa-warning" aria-hidden="true"></span> <span class="icon fa fa-warning" aria-hidden="true"></span>
${_('You must select a session to access the course.')} % if entitlement_expired_at:
${_('You can no longer select a session, your final day to select a session was {entitlement_expired_at}.').format(entitlement_expired_at=entitlement_expired_at)}
% else:
% if entitlement_expiration_date:
${_('You must select a session by {expiration_date} to access the course.').format(expiration_date=entitlement_expiration_date)}
% else:
${_('You must select a session to access the course.')}
% endif
% endif
</span> </span>
% else: % else:
% if isinstance(course_date, basestring): % if isinstance(course_date, basestring):
...@@ -141,9 +149,19 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -141,9 +149,19 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
% endif % endif
% endif % endif
% if entitlement: % if entitlement:
<button class="change-session btn-link ${'hidden' if is_unfulfilled_entitlement else ''}" aria-controls="change-session-${str(entitlement.uuid)}">${_('Change Session')}</button> % if not entitlement_expired_at:
<button class="change-session btn-link ${'hidden' if is_unfulfilled_entitlement else ''}" aria-controls="change-session-${str(entitlement.uuid)}">${_('Change Session')}</button>
% endif
% endif % endif
</span> </span>
% if entitlement and entitlement_expiration_date:
% if not is_unfulfilled_entitlement:
<div class="info-expires-at">
<span class="msg-icon fa fa-info" aria-hidden="true"></span>
${_('You can change sessions until {entitlement_expiration_date}.').format(entitlement_expiration_date=entitlement_expiration_date)}
</div>
% endif
% endif
</div> </div>
<div class="wrapper-course-actions"> <div class="wrapper-course-actions">
<div class="course-actions"> <div class="course-actions">
...@@ -278,8 +296,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -278,8 +296,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
<footer class="wrapper-messages-primary"> <footer class="wrapper-messages-primary">
<div class="messages-list"> <div class="messages-list">
% if entitlement: % if entitlement and not entitlement_expired_at:
<div class="course-entitlement-selection-container ${'' if is_unfulfilled_entitlement else 'hidden'}"></div> <div class="course-entitlement-selection-container ${'' if is_unfulfilled_entitlement else 'hidden'}"></div>
<% print entitlement %>
<%static:require_module module_name="js/learner_dashboard/course_entitlement_factory" class_name="EntitlementFactory"> <%static:require_module module_name="js/learner_dashboard/course_entitlement_factory" class_name="EntitlementFactory">
EntitlementFactory({ EntitlementFactory({
el: '${ '#course-card-' + str(course_card_index) + ' .course-entitlement-selection-container' | n, js_escaped_string }', el: '${ '#course-card-' + str(course_card_index) + ' .course-entitlement-selection-container' | n, js_escaped_string }',
...@@ -293,7 +312,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -293,7 +312,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
entitlementUUID: '${ entitlement.course_uuid | n, js_escaped_string }', entitlementUUID: '${ entitlement.course_uuid | n, js_escaped_string }',
currentSessionId: '${ entitlement_session.course_id if entitlement_session else "" | n, js_escaped_string }', currentSessionId: '${ entitlement_session.course_id if entitlement_session else "" | n, js_escaped_string }',
enrollUrl: '${ reverse('entitlements_api:v1:enrollments', args=[str(entitlement.uuid)]) | n, js_escaped_string }', enrollUrl: '${ reverse('entitlements_api:v1:enrollments', args=[str(entitlement.uuid)]) | n, js_escaped_string }',
courseHomeUrl: '${ course_target | n, js_escaped_string }' courseHomeUrl: '${ course_target | n, js_escaped_string }',
expiredAt: '${ entitlement.expired_at_datetime | n, js_escaped_string }',
daysUntilExpiration: '${ entitlement.get_days_until_expiration() | n, js_escaped_string }',
}); });
</%static:require_module> </%static:require_module>
%endif %endif
......
...@@ -3,12 +3,18 @@ ...@@ -3,12 +3,18 @@
<%def name="online_help_token()"><% return "learnerdashboard" %></%def> <%def name="online_help_token()"><% return "learnerdashboard" %></%def>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! <%!
import crum
import json
import pytz
import third_party_auth
from courseware.context_processor import user_timezone_locale_prefs
from datetime import datetime, timedelta
from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template import RequestContext from django.template import RequestContext
import third_party_auth
from third_party_auth import pipeline from third_party_auth import pipeline
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
import json from util.date_utils import strftime_localized
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.theming import helpers as theming_helpers from openedx.core.djangoapps.theming import helpers as theming_helpers
...@@ -125,6 +131,11 @@ from student.models import CourseEnrollment ...@@ -125,6 +131,11 @@ from student.models import CourseEnrollment
# Check if the course run is an entitlement and if it has an associated session # Check if the course run is an entitlement and if it has an associated session
entitlement = enrollment if isinstance(enrollment, CourseEntitlement) else None entitlement = enrollment if isinstance(enrollment, CourseEntitlement) else None
entitlement_session = entitlement.enrollment_course_run if entitlement else None entitlement_session = entitlement.enrollment_course_run if entitlement else None
entitlement_days_until_expiration = entitlement.get_days_until_expiration() if entitlement else None
entitlement_expiration = datetime.now(tz=pytz.UTC) + timedelta(days=entitlement_days_until_expiration) if (entitlement and entitlement_days_until_expiration < settings.ENTITLEMENT_EXPIRED_ALERT_PERIOD) else None
entitlement_expiration_date = strftime_localized(entitlement_expiration, 'SHORT_DATE') if entitlement and entitlement_expiration else None
entitlement_expired_at = strftime_localized(entitlement.expired_at_datetime, 'SHORT_DATE') if entitlement and entitlement.expired_at_datetime else None
is_fulfilled_entitlement = True if entitlement and entitlement_session else False is_fulfilled_entitlement = True if entitlement and entitlement_session else False
is_unfulfilled_entitlement = True if entitlement and not entitlement_session else False is_unfulfilled_entitlement = True if entitlement and not entitlement_session else False
...@@ -166,7 +177,7 @@ from student.models import CourseEnrollment ...@@ -166,7 +177,7 @@ from student.models import CourseEnrollment
show_consent_link = (session_id in consent_required_courses) show_consent_link = (session_id in consent_required_courses)
course_overview = enrollment.course_overview course_overview = enrollment.course_overview
%> %>
<%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, show_courseware_link=show_courseware_link, cert_status=cert_status, 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_blocked=is_course_blocked, 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' /> <%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_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_blocked=is_course_blocked, 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' />
% endfor % endfor
</ul> </ul>
% else: % else:
......
Markdown is supported
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