Commit 31292a68 by Ayub khan Committed by GitHub

Merge pull request #15602 from…

Merge pull request #15602 from edx/adeel/LEARNER_1426_lms_dashboard_on_enrollment_and_refund_orders_on_demand_version

Improve ECOM connection on student dashboard via on demand ajax calls.
parents aaad66d3 e966188b
...@@ -77,26 +77,6 @@ class RefundableTest(SharedModuleStoreTestCase): ...@@ -77,26 +77,6 @@ class RefundableTest(SharedModuleStoreTestCase):
self.verified_mode.save() self.verified_mode.save()
self.assertTrue(self.enrollment.refundable()) self.assertTrue(self.enrollment.refundable())
def test_refundable_of_purchased_course(self):
""" Assert that courses without a verified mode are not refundable"""
self.client.login(username=self.user.username, password=self.USER_PASSWORD)
course = CourseFactory.create()
CourseModeFactory.create(
course_id=course.id,
mode_slug='honor',
min_price=10,
currency='usd',
mode_display_name='honor',
expiration_datetime=datetime.now(pytz.UTC) + timedelta(days=1)
)
enrollment = CourseEnrollment.enroll(self.user, course.id, mode='honor')
# TODO: Until we can allow course administrators to define a refund period for paid for courses show_refund_option should be False. # pylint: disable=fixme
self.assertFalse(enrollment.refundable())
resp = self.client.post(reverse('student.views.dashboard', args=[]))
self.assertIn('You will not be refunded the amount you paid.', resp.content)
@patch('student.models.CourseEnrollment.refund_cutoff_date') @patch('student.models.CourseEnrollment.refund_cutoff_date')
def test_refundable_when_certificate_exists(self, cutoff_date): def test_refundable_when_certificate_exists(self, cutoff_date):
""" Assert that enrollment is not refundable once a certificat has been generated.""" """ Assert that enrollment is not refundable once a certificat has been generated."""
......
...@@ -15,6 +15,7 @@ from edx_oauth2_provider.constants import AUTHORIZED_CLIENTS_SESSION_KEY ...@@ -15,6 +15,7 @@ from edx_oauth2_provider.constants import AUTHORIZED_CLIENTS_SESSION_KEY
from edx_oauth2_provider.tests.factories import ClientFactory, TrustedClientFactory from edx_oauth2_provider.tests.factories import ClientFactory, TrustedClientFactory
from mock import patch from mock import patch
from pyquery import PyQuery as pq from pyquery import PyQuery as pq
from opaque_keys import InvalidKeyError
from student.cookies import get_user_info_cookie_data from student.cookies import get_user_info_cookie_data
from student.helpers import DISABLE_UNENROLL_CERT_STATES from student.helpers import DISABLE_UNENROLL_CERT_STATES
...@@ -44,7 +45,7 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase): ...@@ -44,7 +45,7 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
""" Create a course and user, then log in. """ """ Create a course and user, then log in. """
super(TestStudentDashboardUnenrollments, self).setUp() super(TestStudentDashboardUnenrollments, self).setUp()
self.user = UserFactory() self.user = UserFactory()
CourseEnrollmentFactory(course_id=self.course.id, user=self.user) self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user)
self.cert_status = None self.cert_status = None
self.client.login(username=self.user.username, password=PASSWORD) self.client.login(username=self.user.username, password=PASSWORD)
...@@ -119,6 +120,30 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase): ...@@ -119,6 +120,30 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_course_run_refund_status_successful(self):
""" Assert that view:course_run_refund_status returns correct Json for successful refund call."""
with patch('student.models.CourseEnrollment.refundable', return_value=True):
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
self.assertEquals(json.loads(response.content), {'course_refundable_status': True})
self.assertEqual(response.status_code, 200)
with patch('student.models.CourseEnrollment.refundable', return_value=False):
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
self.assertEquals(json.loads(response.content), {'course_refundable_status': False})
self.assertEqual(response.status_code, 200)
def test_course_run_refund_status_invalid_course_key(self):
""" Assert that view:course_run_refund_status returns correct Json for Invalid Course Key ."""
with patch('opaque_keys.edx.keys.CourseKey.from_string') as mock_method:
mock_method.side_effect = InvalidKeyError('CourseKey', 'The course key used to get refund status caused \
InvalidKeyError during look up.')
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
self.assertEquals(json.loads(response.content), {'course_refundable_status': ''})
self.assertEqual(response.status_code, 406)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class LogoutTests(TestCase): class LogoutTests(TestCase):
......
...@@ -38,6 +38,9 @@ urlpatterns = ( ...@@ -38,6 +38,9 @@ urlpatterns = (
'password_reset_confirm_wrapper', 'password_reset_confirm_wrapper',
name='password_reset_confirm', name='password_reset_confirm',
), ),
url(r'^course_run/{}/refund_status$'.format(settings.COURSE_ID_PATTERN),
'course_run_refund_status',
name="course_run_refund_status"),
) )
......
...@@ -788,14 +788,6 @@ def dashboard(request): ...@@ -788,14 +788,6 @@ def dashboard(request):
statuses = ["approved", "denied", "pending", "must_reverify"] statuses = ["approved", "denied", "pending", "must_reverify"]
reverifications = reverification_info(statuses) reverifications = reverification_info(statuses)
user_already_has_certs_for = GeneratedCertificate.course_ids_with_certs_for_user(request.user)
show_refund_option_for = frozenset(
enrollment.course_id for enrollment in course_enrollments
if enrollment.refundable(
user_already_has_certs_for=user_already_has_certs_for
)
)
block_courses = frozenset( block_courses = frozenset(
enrollment.course_id for enrollment in course_enrollments enrollment.course_id for enrollment in course_enrollments
if is_course_blocked( if is_course_blocked(
...@@ -861,7 +853,6 @@ def dashboard(request): ...@@ -861,7 +853,6 @@ def dashboard(request):
'verification_status': verification_status, 'verification_status': verification_status,
'verification_status_by_course': verify_status_by_course, 'verification_status_by_course': verify_status_by_course,
'verification_errors': verification_errors, 'verification_errors': verification_errors,
'show_refund_option_for': show_refund_option_for,
'block_courses': block_courses, 'block_courses': block_courses,
'denied_banner': denied_banner, 'denied_banner': denied_banner,
'billing_email': settings.PAYMENT_SUPPORT_EMAIL, 'billing_email': settings.PAYMENT_SUPPORT_EMAIL,
...@@ -892,6 +883,35 @@ def dashboard(request): ...@@ -892,6 +883,35 @@ def dashboard(request):
return response return response
@login_required
def course_run_refund_status(request, course_id):
"""
Get Refundable status for a course.
Arguments:
request: The request object.
course_id (str): The unique identifier for the course.
Returns:
Json response.
"""
try:
course_key = CourseKey.from_string(course_id)
course_enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
except InvalidKeyError:
logging.exception("The course key used to get refund status caused InvalidKeyError during look up.")
return JsonResponse({'course_refundable_status': ''}, status=406)
refundable_status = course_enrollment.refundable()
logging.info("Course refund status for course {0} is {1}".format(course_id, refundable_status))
return JsonResponse({'course_refundable_status': refundable_status}, status=200)
def get_verification_error_reasons_for_display(verification_error_codes): def get_verification_error_reasons_for_display(verification_error_codes):
verification_errors = [] verification_errors = []
verification_error_map = { verification_error_map = {
......
...@@ -135,11 +135,50 @@ class DashboardPage(PageObject): ...@@ -135,11 +135,50 @@ class DashboardPage(PageObject):
else: else:
return None return None
def view_course_unenroll_dialog_message(self, course_id):
"""
Go to the course unenroll dialog message for `course_id` (e.g. edx/Open_DemoX/edx_demo_course)
"""
div_index = self.get_course_actions_link_css(course_id)
button_link_css = "#actions-dropdown-link-{}".format(div_index)
unenroll_css = "#unenroll-{}".format(div_index)
if button_link_css is not None:
self.q(css=button_link_css).first.click()
self.wait_for_element_visibility(unenroll_css, 'Unenroll message dialog is visible.')
self.q(css=unenroll_css).first.click()
self.wait_for_ajax()
return {
'track-info': self.q(css='#track-info').html,
'refund-info': self.q(css='#refund-info').html
}
else:
msg = "No links found for course {0}".format(course_id)
self.warning(msg)
def get_course_actions_link_css(self, course_id):
"""
Return a index for unenroll button with `course_id`.
"""
# Get the link hrefs for all courses
all_divs = self.q(css='div.wrapper-action-more').map(lambda el: el.get_attribute('data-course-key')).results
# Search for the first link that matches the course id
div_index = None
for index in range(len(all_divs)):
if course_id in all_divs[index]:
div_index = index
break
return div_index
def pre_requisite_message_displayed(self): def pre_requisite_message_displayed(self):
""" """
Verify if pre-requisite course messages are being displayed. Verify if pre-requisite course messages are being displayed.
""" """
return self.q(css='li.prerequisites > .tip').visible return self.q(css='div.prerequisites > .tip').visible
def get_course_listings(self): def get_course_listings(self):
"""Retrieve the list of course DOM elements""" """Retrieve the list of course DOM elements"""
......
...@@ -76,19 +76,25 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest): ...@@ -76,19 +76,25 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest):
'org': 'test_org', 'org': 'test_org',
'number': self.unique_id, 'number': self.unique_id,
'run': 'test_run_A', 'run': 'test_run_A',
'display_name': 'Test Course A' 'display_name': 'Test Course A',
'enrollment_mode': 'audit',
'cert_name_long': 'Certificate of Audit Achievement'
}, },
'B': { 'B': {
'org': 'test_org', 'org': 'test_org',
'number': self.unique_id, 'number': self.unique_id,
'run': 'test_run_B', 'run': 'test_run_B',
'display_name': 'Test Course B' 'display_name': 'Test Course B',
'enrollment_mode': 'verified',
'cert_name_long': 'Certificate of Verified Achievement'
}, },
'C': { 'C': {
'org': 'test_org', 'org': 'test_org',
'number': self.unique_id, 'number': self.unique_id,
'run': 'test_run_C', 'run': 'test_run_C',
'display_name': 'Test Course C' 'display_name': 'Test Course C',
'enrollment_mode': 'credit',
'cert_name_long': 'Certificate of Credit Achievement'
} }
} }
...@@ -113,7 +119,8 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest): ...@@ -113,7 +119,8 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest):
) )
course_fixture.add_advanced_settings({ course_fixture.add_advanced_settings({
u"social_sharing_url": {u"value": "http://custom/course/url"} u"social_sharing_url": {u"value": "http://custom/course/url"},
u"cert_name_long": {u"value": value['cert_name_long']}
}) })
course_fixture.install() course_fixture.install()
...@@ -126,7 +133,8 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest): ...@@ -126,7 +133,8 @@ class BaseLmsDashboardTestMultiple(UniqueCourseTest):
self.browser, self.browser,
username=self.username, username=self.username,
email=self.email, email=self.email,
course_id=course_key course_id=course_key,
enrollment_mode=value['enrollment_mode']
).visit() ).visit()
# Navigate the authenticated, enrolled user to the dashboard page and get testing! # Navigate the authenticated, enrolled user to the dashboard page and get testing!
...@@ -346,6 +354,50 @@ class LmsDashboardPageTest(BaseLmsDashboardTest): ...@@ -346,6 +354,50 @@ class LmsDashboardPageTest(BaseLmsDashboardTest):
self.assertEqual(profile_img.attrs('alt')[0], '') self.assertEqual(profile_img.attrs('alt')[0], '')
class LmsDashboardCourseUnEnrollDialogMessageTest(BaseLmsDashboardTestMultiple):
"""
Class to test lms student dashboard unenroll dialog messages.
"""
def test_audit_course_run_unenroll_dialog_msg(self):
"""
Validate unenroll dialog message when user clicks unenroll button for a audit course
"""
self.dashboard_page.visit()
dialog_message = self.dashboard_page.view_course_unenroll_dialog_message(str(self.course_keys['A']))
course_number = self.courses['A']['number']
course_name = self.courses['A']['display_name']
expected_track_message = u'Are you sure you want to unenroll from' + \
u' <span id="unenroll_course_name">' + course_name + u'</span>' + \
u' (<span id="unenroll_course_number">' + course_number + u'</span>)?'
self.assertEqual(dialog_message['track-info'][0], expected_track_message)
def test_verified_course_run_unenroll_dialog_msg(self):
"""
Validate unenroll dialog message when user clicks unenroll button for a verified course passed refund
deadline
"""
self.dashboard_page.visit()
dialog_message = self.dashboard_page.view_course_unenroll_dialog_message(str(self.course_keys['B']))
course_number = self.courses['B']['number']
course_name = self.courses['B']['display_name']
cert_long_name = self.courses['B']['cert_name_long']
expected_track_message = u'Are you sure you want to unenroll from the verified' + \
u' <span id="unenroll_cert_name">' + cert_long_name + u'</span>' + \
u' track of <span id="unenroll_course_name">' + course_name + u'</span>' + \
u' (<span id="unenroll_course_number">' + course_number + u'</span>)?'
expected_refund_message = u'The refund deadline for this course has passed,so you will not receive a refund.'
self.assertEqual(dialog_message['track-info'][0], expected_track_message)
self.assertEqual(dialog_message['refund-info'][0], expected_refund_message)
@attr('a11y') @attr('a11y')
class LmsDashboardA11yTest(BaseLmsDashboardTestMultiple): class LmsDashboardA11yTest(BaseLmsDashboardTestMultiple):
""" """
......
...@@ -79,6 +79,35 @@ ...@@ -79,6 +79,35 @@
return properties; return properties;
} }
function setDialogAttributes(isPaidCourse, certNameLong,
courseNumber, courseName, enrollmentMode, showRefundOption) {
var diagAttr = {};
if (isPaidCourse) {
if (showRefundOption) {
diagAttr['data-refund-info'] = gettext('You will be refunded the amount you paid.');
} else {
diagAttr['data-refund-info'] = gettext('You will not be refunded the amount you paid.');
}
diagAttr['data-track-info'] = gettext('Are you sure you want to unenroll from the purchased course ' +
'%(courseName)s (%(courseNumber)s)?');
} else if (enrollmentMode !== 'verified') {
diagAttr['data-track-info'] = gettext('Are you sure you want to unenroll from %(courseName)s ' +
'(%(courseNumber)s)?');
} else if (showRefundOption) {
diagAttr['data-track-info'] = gettext('Are you sure you want to unenroll from the verified ' +
'%(certNameLong)s track of %(courseName)s (%(courseNumber)s)?');
diagAttr['data-refund-info'] = gettext('You will be refunded the amount you paid.');
} else {
diagAttr['data-track-info'] = gettext('Are you sure you want to unenroll from the verified ' +
'%(certNameLong)s track of %(courseName)s (%(courseNumber)s)?');
diagAttr['data-refund-info'] = gettext('The refund deadline for this course has passed,' +
'so you will not receive a refund.');
}
return diagAttr;
}
$('#failed-verification-button-dismiss').click(function() { $('#failed-verification-button-dismiss').click(function() {
$.ajax({ $.ajax({
url: urls.verifyToggleBannerFailedOff, url: urls.verifyToggleBannerFailedOff,
...@@ -95,29 +124,70 @@ ...@@ -95,29 +124,70 @@
}); });
$('.action-email-settings').click(function(event) { $('.action-email-settings').click(function(event) {
var element = $(event.target); $('#email_settings_course_id').val($(event.target).data('course-id'));
$('#email_settings_course_id').val(element.data('course-id')); $('#email_settings_course_number').text($(event.target).data('course-number'));
$('#email_settings_course_number').text(element.data('course-number'));
if ($(event.target).data('optout') === 'False') { if ($(event.target).data('optout') === 'False') {
$('#receive_emails').prop('checked', true); $('#receive_emails').prop('checked', true);
} }
edx.dashboard.dropdown.toggleCourseActionsDropdownMenu(event); edx.dashboard.dropdown.toggleCourseActionsDropdownMenu(event);
}); });
$('.action-unenroll').click(function(event) { $('.action-unenroll').click(function(event) {
var element = $(event.target); var isPaidCourse = $(event.target).data('course-is-paid-course') === 'True';
var track_info = element.data('track-info'); var certNameLong = $(event.target).data('course-cert-name-long');
var course_number = element.data('course-number'); var enrollmentMode = $(event.target).data('course-enrollment-mode');
var course_name = element.data('course-name');
var cert_name_long = element.data('cert-name-long'); var courseNumber = $(event.target).data('course-number');
$('#track-info').html(interpolate(track_info, { var courseName = $(event.target).data('course-name');
course_number: "<span id='unenroll_course_number'>" + course_number + '</span>', var courseRefundUrl = $(event.target).data('course-refund-url');
course_name: "<span id='unenroll_course_name'>" + course_name + '</span>', var dialogMessageAttr;
cert_name_long: "<span id='unenroll_cert_name'>" + cert_name_long + '</span>'
}, true)); var request = $.ajax({
$('#refund-info').html(element.data('refund-info')); url: courseRefundUrl,
$('#unenroll_course_id').val(element.data('course-id')); method: 'GET',
edx.dashboard.dropdown.toggleCourseActionsDropdownMenu(event); dataType: 'json'
});
request.success(function(data, textStatus, xhr) {
if (xhr.status === 200) {
dialogMessageAttr = setDialogAttributes(isPaidCourse, certNameLong,
courseNumber, courseName, enrollmentMode, data.course_refundable_status);
$('#track-info').empty();
$('#refund-info').empty();
$('#track-info').html(interpolate(dialogMessageAttr['data-track-info'], {
courseNumber: ['<span id="unenroll_course_number">', courseNumber, '</span>'].join(''),
courseName: ['<span id="unenroll_course_name">', courseName, '</span>'].join(''),
certNameLong: ['<span id="unenroll_cert_name">', certNameLong, '</span>'].join('')
}, true));
if ('data-refund-info' in dialogMessageAttr) {
$('#refund-info').text(dialogMessageAttr['data-refund-info']);
}
$('#unenroll_course_id').val($(event.target).data('course-id'));
} else {
$('#unenroll_error').text(
gettext('Unable to determine whether we should give you a refund because' +
' of System Error. Please try again later.')
).stop()
.css('display', 'block');
$('#unenroll_form input[type="submit"]').prop('disabled', true);
}
edx.dashboard.dropdown.toggleCourseActionsDropdownMenu(event);
});
request.fail(function() {
$('#unenroll_error').text(
gettext('Unable to determine whether we should give you a refund because' +
' of System Error. Please try again later.')
).stop()
.css('display', 'block');
$('#unenroll_form input[type="submit"]').prop('disabled', true);
edx.dashboard.dropdown.toggleCourseActionsDropdownMenu(event);
});
}); });
$('#unenroll_form').on('ajax:complete', function(event, xhr) { $('#unenroll_form').on('ajax:complete', function(event, xhr) {
...@@ -127,9 +197,10 @@ ...@@ -127,9 +197,10 @@
location.href = urls.signInUser + '?course_id=' + location.href = urls.signInUser + '?course_id=' +
encodeURIComponent($('#unenroll_course_id').val()) + '&enrollment_action=unenroll'; encodeURIComponent($('#unenroll_course_id').val()) + '&enrollment_action=unenroll';
} else { } else {
$('#unenroll_error').html( $('#unenroll_error').text(
xhr.responseText ? xhr.responseText : gettext('An error occurred. Please try again later.') xhr.responseText ? xhr.responseText : gettext('An error occurred. Please try again later.')
).stop().css('display', 'block'); ).stop()
.css('display', 'block');
} }
}); });
...@@ -153,7 +224,6 @@ ...@@ -153,7 +224,6 @@
}); });
$('.action-email-settings').each(function(index) { $('.action-email-settings').each(function(index) {
$(this).attr('id', 'email-settings-' + index);
// a bit of a hack, but gets the unique selector for the modal trigger // a bit of a hack, but gets the unique selector for the modal trigger
var trigger = '#' + $(this).attr('id'); var trigger = '#' + $(this).attr('id');
accessibleModal( accessibleModal(
...@@ -161,11 +231,11 @@ ...@@ -161,11 +231,11 @@
'#email-settings-modal .close-modal', '#email-settings-modal .close-modal',
'#email-settings-modal', '#email-settings-modal',
'#dashboard-main' '#dashboard-main'
); );
$(this).attr('id', 'email-settings-' + index);
}); });
$('.action-unenroll').each(function(index) { $('.action-unenroll').each(function(index) {
$(this).attr('id', 'unenroll-' + index);
// a bit of a hack, but gets the unique selector for the modal trigger // a bit of a hack, but gets the unique selector for the modal trigger
var trigger = '#' + $(this).attr('id'); var trigger = '#' + $(this).attr('id');
accessibleModal( accessibleModal(
...@@ -173,7 +243,8 @@ ...@@ -173,7 +243,8 @@
'#unenroll-modal .close-modal', '#unenroll-modal .close-modal',
'#unenroll-modal', '#unenroll-modal',
'#dashboard-main' '#dashboard-main'
); );
$(this).attr('id', 'unenroll-' + index);
}); });
$('#unregister_block_course').click(function(event) { $('#unregister_block_course').click(function(event) {
......
...@@ -110,13 +110,12 @@ from openedx.core.djangolib.markup import HTML, Text ...@@ -110,13 +110,12 @@ from openedx.core.djangolib.markup import HTML, Text
<% credit_status = credit_statuses.get(enrollment.course_id) %> <% credit_status = credit_statuses.get(enrollment.course_id) %>
<% show_email_settings = (enrollment.course_id in show_email_settings_for) %> <% show_email_settings = (enrollment.course_id in show_email_settings_for) %>
<% course_mode_info = all_course_modes.get(enrollment.course_id) %> <% course_mode_info = all_course_modes.get(enrollment.course_id) %>
<% show_refund_option = (enrollment.course_id in show_refund_option_for) %>
<% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %> <% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %>
<% is_course_blocked = (enrollment.course_id in block_courses) %> <% is_course_blocked = (enrollment.course_id in block_courses) %>
<% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %> <% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %>
<% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %> <% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %>
<% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %> <% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %>
<%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, 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, show_refund_option=show_refund_option, 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' /> <%include file='dashboard/_dashboard_course_listing.html' args='course_overview=enrollment.course_overview, enrollment=enrollment, 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' />
% endfor % endfor
</ul> </ul>
......
<%page args="course_overview, enrollment, show_courseware_link, cert_status, can_unenroll, credit_status, show_email_settings, course_mode_info, show_refund_option, is_paid_course, is_course_blocked, verification_status, course_requirements, dashboard_index, share_settings, related_programs, display_course_modes_on_dashboard" expression_filter="h"/> <%page args="course_overview, enrollment, 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" expression_filter="h"/>
<%! <%!
import urllib import urllib
...@@ -208,6 +208,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -208,6 +208,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
% endif % endif
% endif % endif
<div class="wrapper-action-more" data-course-key="${enrollment.course_id}"> <div class="wrapper-action-more" data-course-key="${enrollment.course_id}">
<button type="button" class="action action-more" id="actions-dropdown-link-${dashboard_index}" aria-haspopup="true" aria-expanded="false" aria-controls="actions-dropdown-${dashboard_index}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"> <button type="button" class="action action-more" id="actions-dropdown-link-${dashboard_index}" aria-haspopup="true" aria-expanded="false" aria-controls="actions-dropdown-${dashboard_index}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}">
<span class="sr">${_('Course options for')}</span> <span class="sr">${_('Course options for')}</span>
...@@ -220,77 +221,34 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -220,77 +221,34 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
<ul class="actions-dropdown-list" id="actions-dropdown-list-${dashboard_index}" aria-label="${_('Available Actions')}" role="menu"> <ul class="actions-dropdown-list" id="actions-dropdown-list-${dashboard_index}" aria-label="${_('Available Actions')}" role="menu">
% if can_unenroll: % if can_unenroll:
<li class="actions-item" id="actions-item-unenroll-${dashboard_index}"> <li class="actions-item" id="actions-item-unenroll-${dashboard_index}">
% if is_paid_course and show_refund_option: <% course_refund_url = reverse('course_run_refund_status', args=[unicode(course_overview.id)]) %>
% if not is_course_blocked: % if not is_course_blocked:
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" <a href="#unenroll-modal" class="action action-unenroll" rel="leanModal"
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}" data-course-id="${course_overview.id}"
data-refund-info="${_("You will be refunded the amount you paid.")}"> data-course-number="${course_overview.number}"
${_('Unenroll')} data-course-name="${course_overview.display_name_with_default}"
</a> data-dashboard-index="${dashboard_index}"
% else: data-course-refund-url="${course_refund_url}"
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-course-is-paid-course="${is_paid_course}"
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}" data-course-cert-name-long="${cert_name_long}"
data-refund-info="${_("You will be refunded the amount you paid.")}"> data-course-enrollment-mode="${enrollment.mode}">
${_('Unenroll')} ${_('Unenroll')}
</a> </a>
% endif % else:
% elif is_paid_course and not show_refund_option: <a class="action action-unenroll is-disabled"
% if not is_course_blocked: data-course-id="${course_overview.id}"
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-course-number="${course_overview.number}"
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}" data-course-name="${course_overview.display_name_with_default}"
data-refund-info="${_("You will not be refunded the amount you paid.")}"> data-dashboard-index="${dashboard_index}"
${_('Unenroll')} data-course-refund-url="${course_refund_url}"
</a> data-course-is-paid-course="${is_paid_course}"
% else: data-course-cert-name-long="${cert_name_long}"
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-course-enrollment-mode="${enrollment.mode}">
data-track-info="${_("Are you sure you want to unenroll from the purchased course %(course_name)s (%(course_number)s)?")}" ${_('Unenroll')}
data-refund-info="${_("You will not be refunded the amount you paid.")}"> </a>
${_('Unenroll')} % endif
</a> </li>
% endif % endif
% elif enrollment.mode != "verified":
% if not is_course_blocked:
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?")}">
${_('Unenroll')}
</a>
% else:
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}"
data-track-info="${_("Are you sure you want to unenroll from %(course_name)s (%(course_number)s)?")}">
${_('Unenroll')}
</a>
% endif
% elif show_refund_option:
% if not is_course_blocked:
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
data-refund-info="${_("You will be refunded the amount you paid.")}">
${_('Unenroll')}
</a>
% else:
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
data-refund-info="${_("You will be refunded the amount you paid.")}">
${_('Unenroll')}
</a>
% endif
% else:
% if not is_course_blocked:
<a href="#unenroll-modal" class="action action-unenroll" rel="leanModal" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.")}">
${_('Unenroll')}
</a>
% else:
<a class="action action-unenroll is-disabled" data-course-id="${course_overview.id}" data-course-number="${course_overview.number}" data-course-name="${course_overview.display_name_with_default}" data-dashboard-index="${dashboard_index}" data-cert-name-long="${cert_name_long}"
data-track-info="${_("Are you sure you want to unenroll from the verified %(cert_name_long)s track of %(course_name)s (%(course_number)s)?")}"
data-refund-info="${_("The refund deadline for this course has passed, so you will not receive a refund.")}">
${_('Unenroll')}
</a>
% endif
% endif
</li>
% endif
<li class="actions-item" id="actions-item-email-settings-${dashboard_index}"> <li class="actions-item" id="actions-item-email-settings-${dashboard_index}">
% if show_email_settings: % if show_email_settings:
% if not is_course_blocked: % if not is_course_blocked:
...@@ -308,7 +266,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -308,7 +266,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
</div> </div>
</section> </section>
<footer class="wrapper-messages-primary"> <footer class="wrapper-messages-primary">
<ul class="messages-list"> <div class="messages-list">
% if related_programs: % if related_programs:
<div class="message message-related-programs is-shown"> <div class="message message-related-programs is-shown">
<span class="related-programs-preface" tabindex="0">${_('Related Programs')}:</span> <span class="related-programs-preface" tabindex="0">${_('Related Programs')}:</span>
...@@ -439,7 +397,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -439,7 +397,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
% if course_requirements: % if course_requirements:
## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element ## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element
<% prc_target = reverse('about_course', args=[unicode(course_requirements['courses'][0]['key'])]) %> <% prc_target = reverse('about_course', args=[unicode(course_requirements['courses'][0]['key'])]) %>
<li class="prerequisites"> <div class="prerequisites">
<p class="tip"> <p class="tip">
${Text(_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.")).format( ${Text(_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.")).format(
link_start=HTML('<a href="{}">').format(prc_target), link_start=HTML('<a href="{}">').format(prc_target),
...@@ -447,9 +405,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_ ...@@ -447,9 +405,9 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
prc_display=course_requirements['courses'][0]['display'], prc_display=course_requirements['courses'][0]['display'],
)} )}
</p> </p>
</li> </div>
% endif % endif
</ul> </div>
</footer> </footer>
</article> </article>
</div> </div>
......
...@@ -109,13 +109,12 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers ...@@ -109,13 +109,12 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
<% credit_status = credit_statuses.get(enrollment.course_id) %> <% credit_status = credit_statuses.get(enrollment.course_id) %>
<% show_email_settings = (enrollment.course_id in show_email_settings_for) %> <% show_email_settings = (enrollment.course_id in show_email_settings_for) %>
<% course_mode_info = all_course_modes.get(enrollment.course_id) %> <% course_mode_info = all_course_modes.get(enrollment.course_id) %>
<% show_refund_option = (enrollment.course_id in show_refund_option_for) %>
<% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %> <% is_paid_course = (enrollment.course_id in enrolled_courses_either_paid) %>
<% is_course_blocked = (enrollment.course_id in block_courses) %> <% is_course_blocked = (enrollment.course_id in block_courses) %>
<% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %> <% course_verification_status = verification_status_by_course.get(enrollment.course_id, {}) %>
<% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %> <% course_requirements = courses_requirements_not_met.get(enrollment.course_id) %>
<% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %> <% related_programs = inverted_programs.get(unicode(enrollment.course_id)) %>
<%include file = 'dashboard/_dashboard_course_listing.html' args="course_overview=enrollment.course_overview, enrollment=enrollment, 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, show_refund_option=show_refund_option, 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" /> <%include file = 'dashboard/_dashboard_course_listing.html' args="course_overview=enrollment.course_overview, enrollment=enrollment, 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" />
% endfor % endfor
</ul> </ul>
......
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