diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py
index a78b4effe5..d21d4e80eb 100644
--- a/common/djangoapps/student/models.py
+++ b/common/djangoapps/student/models.py
@@ -18,6 +18,8 @@ from pytz import UTC
import uuid
from collections import defaultdict
from dogapi import dog_stats_api
+from django.db.models import Q
+import pytz
from django.conf import settings
from django.utils import timezone
@@ -960,6 +962,17 @@ class CourseEnrollment(models.Model):
d['total'] = total
return d
+ def is_paid_course(self):
+ """
+ Returns True, if course is paid
+ """
+ paid_course = CourseMode.objects.filter(Q(course_id=self.course_id) & Q(mode_slug='honor') &
+ (Q(expiration_datetime__isnull=True) | Q(expiration_datetime__gte=datetime.now(pytz.UTC)))).exclude(min_price=0)
+ if paid_course:
+ return True
+
+ return False
+
def activate(self):
"""Makes this `CourseEnrollment` record active. Saves immediately."""
self.update_enrollment(is_active=True)
@@ -991,6 +1004,8 @@ class CourseEnrollment(models.Model):
if GeneratedCertificate.certificate_for_student(self.user, self.course_id) is not None:
return False
+ #TODO - When Course administrators to define a refund period for paid courses then refundable will be supported. # pylint: disable=W0511
+
course_mode = CourseMode.mode_for_course(self.course_id, 'verified')
if course_mode is None:
return False
diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py
index 0be58d64e5..9afc044f57 100644
--- a/common/djangoapps/student/tests/tests.py
+++ b/common/djangoapps/student/tests/tests.py
@@ -148,11 +148,6 @@ class DashboardTest(TestCase):
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG)
self.assertIsNotNone(self.course)
self.user = UserFactory.create(username="jack", email="jack@fake.edx.org", password='test')
- CourseModeFactory.create(
- course_id=self.course.id,
- mode_slug='honor',
- mode_display_name='Honor Code',
- )
self.client = Client()
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@@ -230,6 +225,26 @@ class DashboardTest(TestCase):
verified_mode.save()
self.assertFalse(enrollment.refundable())
+ @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+ def test_refundable_of_purchased_course(self):
+
+ self.client.login(username="jack", password="test")
+ CourseModeFactory.create(
+ course_id=self.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, self.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=W0511
+ 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)
+
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_refundable_when_certificate_exists(self):
verified_mode = CourseModeFactory.create(
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index edcf9278ce..df8b9ce10a 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -483,6 +483,8 @@ def dashboard(request):
show_refund_option_for = frozenset(course.id for course, _enrollment in course_enrollment_pairs
if _enrollment.refundable())
+ enrolled_courses_either_paid = frozenset(course.id for course, _enrollment in course_enrollment_pairs
+ if _enrollment.is_paid_course())
# get info w.r.t ExternalAuthMap
external_auth_map = None
try:
@@ -535,6 +537,7 @@ def dashboard(request):
'duplicate_provider': None,
'logout_url': reverse(logout_user),
'platform_name': settings.PLATFORM_NAME,
+ 'enrolled_courses_either_paid': enrolled_courses_either_paid,
'provider_states': [],
}
diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html
index e03cda79ee..4f086d901c 100644
--- a/lms/templates/dashboard.html
+++ b/lms/templates/dashboard.html
@@ -302,7 +302,8 @@
<% show_email_settings = (course.id in show_email_settings_for) %>
<% course_mode_info = all_course_modes.get(course.id) %>
<% show_refund_option = (course.id in show_refund_option_for) %>
- <%include file='dashboard/_dashboard_course_listing.html' args="course=course, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_status, show_email_settings=show_email_settings, course_mode_info=course_mode_info, show_refund_option = show_refund_option" />
+ <% is_paid_course = (course.id in enrolled_courses_either_paid) %>
+ <%include file='dashboard/_dashboard_course_listing.html' args="course=course, enrollment=enrollment, show_courseware_link=show_courseware_link, cert_status=cert_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" />
% endfor
diff --git a/lms/templates/dashboard/_dashboard_course_listing.html b/lms/templates/dashboard/_dashboard_course_listing.html
index 779de56636..d46634d520 100644
--- a/lms/templates/dashboard/_dashboard_course_listing.html
+++ b/lms/templates/dashboard/_dashboard_course_listing.html
@@ -1,4 +1,4 @@
-<%page args="course, enrollment, show_courseware_link, cert_status, show_email_settings, course_mode_info, show_refund_option" />
+<%page args="course, enrollment, show_courseware_link, cert_status, show_email_settings, course_mode_info, show_refund_option, is_paid_course" />
<%! from django.utils.translation import ugettext as _ %>
<%!
@@ -126,7 +126,19 @@
% endif
% endif
- % if enrollment.mode != "verified":
+ % if is_paid_course and show_refund_option:
+ ## Translators: The course's name will be added to the end of this sentence.
+
+ ${_('Unregister')}
+
+ % elif is_paid_course and not show_refund_option:
+ ## Translators: The course's name will be added to the end of this sentence.
+
+ ${_('Unregister')}
+
+ % elif enrollment.mode != "verified":
## Translators: The course's name will be added to the end of this sentence.
${_('Unregister')}