Moved can_refund logic to CourseEnrollment
This commit is contained in:
@@ -26,6 +26,7 @@ from django.dispatch import receiver
|
|||||||
import django.dispatch
|
import django.dispatch
|
||||||
from django.forms import ModelForm, forms
|
from django.forms import ModelForm, forms
|
||||||
|
|
||||||
|
from course_modes.models import CourseMode
|
||||||
import comment_client as cc
|
import comment_client as cc
|
||||||
from pytz import UTC
|
from pytz import UTC
|
||||||
|
|
||||||
@@ -926,6 +927,18 @@ class CourseEnrollment(models.Model):
|
|||||||
self.is_active = False
|
self.is_active = False
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
def refundable(self):
|
||||||
|
"""
|
||||||
|
For paid/verified certificates, students may receive a refund IFF they have
|
||||||
|
a verified certificate and the deadline for refunds has not yet passed.
|
||||||
|
"""
|
||||||
|
course_mode = CourseMode.mode_for_course(self.course_id, 'verified')
|
||||||
|
if course_mode is None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CourseEnrollmentAllowed(models.Model):
|
class CourseEnrollmentAllowed(models.Model):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -256,6 +256,22 @@ class DashboardTest(TestCase):
|
|||||||
self.assertFalse(course_mode_info['show_upsell'])
|
self.assertFalse(course_mode_info['show_upsell'])
|
||||||
self.assertIsNone(course_mode_info['days_for_upsell'])
|
self.assertIsNone(course_mode_info['days_for_upsell'])
|
||||||
|
|
||||||
|
def test_refundable(self):
|
||||||
|
verified_mode = CourseModeFactory.create(
|
||||||
|
course_id=self.course.id,
|
||||||
|
mode_slug='verified',
|
||||||
|
mode_display_name='Verified',
|
||||||
|
expiration_date=(datetime.now(pytz.UTC) + timedelta(days=1)).date()
|
||||||
|
)
|
||||||
|
enrollment = CourseEnrollment.enroll(self.user, self.course.id, mode='verified')
|
||||||
|
|
||||||
|
self.assertTrue(enrollment.refundable())
|
||||||
|
|
||||||
|
verified_mode.expiration_date = (datetime.now(pytz.UTC) - timedelta(days=1)).date()
|
||||||
|
verified_mode.save()
|
||||||
|
self.assertFalse(enrollment.refundable())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EnrollInCourseTest(TestCase):
|
class EnrollInCourseTest(TestCase):
|
||||||
"""Tests enrolling and unenrolling in courses."""
|
"""Tests enrolling and unenrolling in courses."""
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ from student.forms import PasswordResetFormNoActive
|
|||||||
|
|
||||||
from verify_student.models import SoftwareSecurePhotoVerification
|
from verify_student.models import SoftwareSecurePhotoVerification
|
||||||
from certificates.models import CertificateStatuses, certificate_status_for_student
|
from certificates.models import CertificateStatuses, certificate_status_for_student
|
||||||
from shoppingcart.models import CertificateItem
|
|
||||||
|
|
||||||
from xmodule.course_module import CourseDescriptor
|
from xmodule.course_module import CourseDescriptor
|
||||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||||
@@ -341,7 +340,7 @@ def dashboard(request):
|
|||||||
verification_status, verification_msg = SoftwareSecurePhotoVerification.user_status(user)
|
verification_status, verification_msg = SoftwareSecurePhotoVerification.user_status(user)
|
||||||
|
|
||||||
show_refund_option_for = frozenset(course.id for course, _enrollment in courses
|
show_refund_option_for = frozenset(course.id for course, _enrollment in courses
|
||||||
if (has_access(request.user, course, 'refund') and (_enrollment.mode == "verified")))
|
if _enrollment.refundable())
|
||||||
|
|
||||||
# get info w.r.t ExternalAuthMap
|
# get info w.r.t ExternalAuthMap
|
||||||
external_auth_map = None
|
external_auth_map = None
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from xmodule.modulestore import Location
|
|||||||
from xmodule.x_module import XModule, XModuleDescriptor
|
from xmodule.x_module import XModule, XModuleDescriptor
|
||||||
|
|
||||||
from student.models import CourseEnrollmentAllowed
|
from student.models import CourseEnrollmentAllowed
|
||||||
from course_modes.models import CourseMode
|
|
||||||
from external_auth.models import ExternalAuthMap
|
from external_auth.models import ExternalAuthMap
|
||||||
from courseware.masquerade import is_masquerading_as_student
|
from courseware.masquerade import is_masquerading_as_student
|
||||||
from django.utils.timezone import UTC
|
from django.utils.timezone import UTC
|
||||||
@@ -203,24 +202,11 @@ def _has_access_course_desc(user, course, action):
|
|||||||
|
|
||||||
return can_enroll() or can_load()
|
return can_enroll() or can_load()
|
||||||
|
|
||||||
def can_refund():
|
|
||||||
"""
|
|
||||||
For paid/verified certificates, students may receive a refund IFF they have
|
|
||||||
a verified certificate and the deadline for refunds has not yet passed.
|
|
||||||
"""
|
|
||||||
course_mode = CourseMode.mode_for_course(course.id, 'verified')
|
|
||||||
if course_mode is None:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
checkers = {
|
checkers = {
|
||||||
'load': can_load,
|
'load': can_load,
|
||||||
'load_forum': can_load_forum,
|
'load_forum': can_load_forum,
|
||||||
'enroll': can_enroll,
|
'enroll': can_enroll,
|
||||||
'see_exists': see_exists,
|
'see_exists': see_exists,
|
||||||
'refund': can_refund,
|
|
||||||
'staff': lambda: _has_staff_access_to_descriptor(user, course),
|
'staff': lambda: _has_staff_access_to_descriptor(user, course),
|
||||||
'instructor': lambda: _has_instructor_access_to_descriptor(user, course),
|
'instructor': lambda: _has_instructor_access_to_descriptor(user, course),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ from .factories import CourseEnrollmentAllowedFactory
|
|||||||
import datetime
|
import datetime
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from student.tests.factories import UserFactory
|
|
||||||
from xmodule.modulestore.tests.factories import CourseFactory
|
|
||||||
from course_modes.tests.factories import CourseModeFactory
|
|
||||||
|
|
||||||
|
|
||||||
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
||||||
class AccessTestCase(TestCase):
|
class AccessTestCase(TestCase):
|
||||||
@@ -116,28 +112,3 @@ class AccessTestCase(TestCase):
|
|||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# Non-staff cannot enroll outside the open enrollment period if not specifically allowed
|
# Non-staff cannot enroll outside the open enrollment period if not specifically allowed
|
||||||
|
|
||||||
def test__has_access_refund(self):
|
|
||||||
today = datetime.datetime.now(pytz.utc)
|
|
||||||
one_day_extra = datetime.timedelta(days=1)
|
|
||||||
user = UserFactory.create()
|
|
||||||
|
|
||||||
course_nonrefundable_id = 'nonrefundable/test/Test_Course'
|
|
||||||
course_nonrefundable = CourseFactory.create(org='nonrefundable', number='test', run='course', display_name='Test Course')
|
|
||||||
course_mode_nonrefundable = CourseModeFactory.create(course_id=course_nonrefundable_id,
|
|
||||||
mode_slug='verified',
|
|
||||||
expiration_date=(today - one_day_extra))
|
|
||||||
course_mode_nonrefundable.save()
|
|
||||||
|
|
||||||
course_refundable_id = 'refundable/test/Test_Course'
|
|
||||||
course_refundable = CourseFactory.create(org='refundable', number='test', run='course', display_name='Test Course')
|
|
||||||
course_mode_refundable = CourseModeFactory.create(course_id=course_refundable_id,
|
|
||||||
mode_slug='verified',
|
|
||||||
expiration_date=(today + one_day_extra))
|
|
||||||
course_mode_refundable.save()
|
|
||||||
|
|
||||||
# User cannot receive a refund one day after the expiration date
|
|
||||||
self.assertFalse(access._has_access_course_desc(user, course_nonrefundable, 'refund'))
|
|
||||||
|
|
||||||
# After two weeks, user may no longer receive a refund
|
|
||||||
self.assertTrue(access._has_access_course_desc(user, course_refundable, 'refund'))
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
<% show_email_settings = (course.id in show_email_settings_for) %>
|
<% show_email_settings = (course.id in show_email_settings_for) %>
|
||||||
<% course_mode_info = all_course_modes.get(course.id) %>
|
<% course_mode_info = all_course_modes.get(course.id) %>
|
||||||
<% show_refund_option = (course.id in show_refund_option_for) %>
|
<% 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" />
|
<%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" />
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user