Merge pull request #12315 from edx/mattdrayer/course-mode-bulk-sku
mattdrayer/course-mode-bulk-sku: Add new CourseMode field
This commit is contained in:
@@ -184,7 +184,8 @@ class CourseModeAdmin(admin.ModelAdmin):
|
||||
'currency',
|
||||
'_expiration_datetime',
|
||||
'verification_deadline',
|
||||
'sku'
|
||||
'sku',
|
||||
'bulk_sku'
|
||||
)
|
||||
|
||||
search_fields = ('course_id',)
|
||||
@@ -195,7 +196,8 @@ class CourseModeAdmin(admin.ModelAdmin):
|
||||
'mode_slug',
|
||||
'min_price',
|
||||
'expiration_datetime_custom',
|
||||
'sku'
|
||||
'sku',
|
||||
'bulk_sku'
|
||||
)
|
||||
|
||||
def expiration_datetime_custom(self, obj):
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('course_modes', '0006_auto_20160208_1407'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='coursemode',
|
||||
name='bulk_sku',
|
||||
field=models.CharField(help_text='This is the bulk SKU (stock keeping unit) of this mode in the external ecommerce service.', max_length=255, null=True, verbose_name=b'Bulk SKU', blank=True),
|
||||
),
|
||||
]
|
||||
@@ -22,6 +22,7 @@ Mode = namedtuple('Mode',
|
||||
'expiration_datetime',
|
||||
'description',
|
||||
'sku',
|
||||
'bulk_sku',
|
||||
])
|
||||
|
||||
|
||||
@@ -96,6 +97,17 @@ class CourseMode(models.Model):
|
||||
)
|
||||
)
|
||||
|
||||
# Optional bulk order SKU for integration with the ecommerce service
|
||||
bulk_sku = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="Bulk SKU",
|
||||
help_text=_(
|
||||
u"This is the bulk SKU (stock keeping unit) of this mode in the external ecommerce service."
|
||||
)
|
||||
)
|
||||
|
||||
HONOR = 'honor'
|
||||
PROFESSIONAL = 'professional'
|
||||
VERIFIED = "verified"
|
||||
@@ -103,7 +115,7 @@ class CourseMode(models.Model):
|
||||
NO_ID_PROFESSIONAL_MODE = "no-id-professional"
|
||||
CREDIT_MODE = "credit"
|
||||
|
||||
DEFAULT_MODE = Mode(AUDIT, _('Audit'), 0, '', 'usd', None, None, None)
|
||||
DEFAULT_MODE = Mode(AUDIT, _('Audit'), 0, '', 'usd', None, None, None, None)
|
||||
DEFAULT_MODE_SLUG = AUDIT
|
||||
|
||||
# Modes that allow a student to pursue a verified certificate
|
||||
@@ -123,7 +135,7 @@ class CourseMode(models.Model):
|
||||
# "honor" to "audit", we still need to have the shoppingcart
|
||||
# use "honor"
|
||||
DEFAULT_SHOPPINGCART_MODE_SLUG = HONOR
|
||||
DEFAULT_SHOPPINGCART_MODE = Mode(HONOR, _('Honor'), 0, '', 'usd', None, None, None)
|
||||
DEFAULT_SHOPPINGCART_MODE = Mode(HONOR, _('Honor'), 0, '', 'usd', None, None, None, None)
|
||||
|
||||
class Meta(object):
|
||||
unique_together = ('course_id', 'mode_slug', 'currency')
|
||||
@@ -625,7 +637,8 @@ class CourseMode(models.Model):
|
||||
self.currency,
|
||||
self.expiration_datetime,
|
||||
self.description,
|
||||
self.sku
|
||||
self.sku,
|
||||
self.bulk_sku
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
|
||||
@@ -77,7 +77,7 @@ class CourseModeModelTest(TestCase):
|
||||
|
||||
self.create_mode('verified', 'Verified Certificate', 10)
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
mode = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None)
|
||||
mode = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None, None)
|
||||
self.assertEqual([mode], modes)
|
||||
|
||||
modes_dict = CourseMode.modes_for_course_dict(self.course_key)
|
||||
@@ -89,8 +89,8 @@ class CourseModeModelTest(TestCase):
|
||||
"""
|
||||
Finding the modes when there's multiple modes
|
||||
"""
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None)
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None, None)
|
||||
set_modes = [mode1, mode2]
|
||||
for mode in set_modes:
|
||||
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices)
|
||||
@@ -109,9 +109,9 @@ class CourseModeModelTest(TestCase):
|
||||
self.assertEqual(0, CourseMode.min_course_price_for_currency(self.course_key, 'usd'))
|
||||
|
||||
# create some modes
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 10, '', 'usd', None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 20, '', 'usd', None, None, None)
|
||||
mode3 = Mode(u'honor', u'Honor Code Certificate', 80, '', 'cny', None, None, None)
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 10, '', 'usd', None, None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 20, '', 'usd', None, None, None, None)
|
||||
mode3 = Mode(u'honor', u'Honor Code Certificate', 80, '', 'cny', None, None, None, None)
|
||||
set_modes = [mode1, mode2, mode3]
|
||||
for mode in set_modes:
|
||||
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices, mode.currency)
|
||||
@@ -126,7 +126,7 @@ class CourseModeModelTest(TestCase):
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
self.assertEqual([CourseMode.DEFAULT_MODE], modes)
|
||||
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None)
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None, None)
|
||||
self.create_mode(mode1.slug, mode1.name, mode1.min_price, mode1.suggested_prices)
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
self.assertEqual([mode1], modes)
|
||||
@@ -134,7 +134,17 @@ class CourseModeModelTest(TestCase):
|
||||
expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
expired_mode.expiration_datetime = expiration_datetime
|
||||
expired_mode.save()
|
||||
expired_mode_value = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', expiration_datetime, None, None)
|
||||
expired_mode_value = Mode(
|
||||
u'verified',
|
||||
u'Verified Certificate',
|
||||
10,
|
||||
'',
|
||||
'usd',
|
||||
expiration_datetime,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
)
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
self.assertEqual([expired_mode_value, mode1], modes)
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
|
||||
# Create the course modes
|
||||
prof_course = CourseFactory.create()
|
||||
CourseModeFactory(mode_slug=CourseMode.NO_ID_PROFESSIONAL_MODE, course_id=prof_course.id,
|
||||
min_price=100, sku='TEST')
|
||||
min_price=100, sku='TEST', bulk_sku="BULKTEST")
|
||||
ecomm_test_utils.update_commerce_config(enabled=True)
|
||||
# Enroll the user in the test course
|
||||
CourseEnrollmentFactory(
|
||||
@@ -304,7 +304,7 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
expected_mode = [Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None)]
|
||||
expected_mode = [Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None, None)]
|
||||
course_mode = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
self.assertEquals(course_mode, expected_mode)
|
||||
@@ -328,7 +328,19 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
expected_mode = [Mode(mode_slug, mode_display_name, min_price, suggested_prices, currency, None, None, None)]
|
||||
expected_mode = [
|
||||
Mode(
|
||||
mode_slug,
|
||||
mode_display_name,
|
||||
min_price,
|
||||
suggested_prices,
|
||||
currency,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
)
|
||||
]
|
||||
course_mode = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
self.assertEquals(course_mode, expected_mode)
|
||||
@@ -351,8 +363,8 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
|
||||
url = reverse('create_mode', args=[unicode(self.course.id)])
|
||||
self.client.get(url, parameters)
|
||||
|
||||
honor_mode = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None)
|
||||
verified_mode = Mode(u'verified', u'Verified Certificate', 10, '10,20', 'usd', None, None, None)
|
||||
honor_mode = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None, None)
|
||||
verified_mode = Mode(u'verified', u'Verified Certificate', 10, '10,20', 'usd', None, None, None, None)
|
||||
expected_modes = [honor_mode, verified_mode]
|
||||
course_modes = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ class ChooseModeView(View):
|
||||
context["use_ecommerce_payment_flow"] = ecommerce_service.is_enabled(request.user)
|
||||
context["ecommerce_payment_page"] = ecommerce_service.payment_page_url()
|
||||
context["sku"] = verified_mode.sku
|
||||
context["bulk_sku"] = verified_mode.bulk_sku
|
||||
|
||||
return render_to_response("course_modes/choose.html", context)
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ def get_enrollments(user_id):
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": False
|
||||
@@ -78,7 +79,8 @@ def get_enrollments(user_id):
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": True
|
||||
@@ -124,7 +126,8 @@ def get_enrollment(user_id, course_id):
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": False
|
||||
@@ -175,7 +178,8 @@ def add_enrollment(user_id, course_id, mode=None, is_active=True):
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": False
|
||||
@@ -227,7 +231,8 @@ def update_enrollment(user_id, course_id, mode=None, is_active=None, enrollment_
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": False
|
||||
@@ -280,7 +285,8 @@ def get_course_enrollment_details(course_id, include_expired=False):
|
||||
"currency": "usd",
|
||||
"expiration_datetime": null,
|
||||
"description": null,
|
||||
"sku": null
|
||||
"sku": null,
|
||||
"bulk_sku": null
|
||||
}
|
||||
],
|
||||
"invite_only": False
|
||||
|
||||
@@ -98,3 +98,4 @@ class ModeSerializer(serializers.Serializer):
|
||||
expiration_datetime = serializers.DateTimeField()
|
||||
description = serializers.CharField()
|
||||
sku = serializers.CharField()
|
||||
bulk_sku = serializers.CharField()
|
||||
|
||||
@@ -402,6 +402,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
|
||||
mode_slug=CourseMode.HONOR,
|
||||
mode_display_name=CourseMode.HONOR,
|
||||
sku='123',
|
||||
bulk_sku="BULK123"
|
||||
)
|
||||
resp = self.client.get(
|
||||
reverse('courseenrollmentdetails', kwargs={"course_id": unicode(self.course.id)})
|
||||
@@ -413,6 +414,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
|
||||
mode = data['course_modes'][0]
|
||||
self.assertEqual(mode['slug'], CourseMode.HONOR)
|
||||
self.assertEqual(mode['sku'], '123')
|
||||
self.assertEqual(mode['bulk_sku'], 'BULK123')
|
||||
self.assertEqual(mode['name'], CourseMode.HONOR)
|
||||
|
||||
def test_get_course_details_with_credit_course(self):
|
||||
|
||||
@@ -504,6 +504,7 @@ def complete_course_mode_info(course_id, enrollment, modes=None):
|
||||
if CourseMode.VERIFIED in modes and enrollment.mode in CourseMode.UPSELL_TO_VERIFIED_MODES:
|
||||
mode_info['show_upsell'] = True
|
||||
mode_info['verified_sku'] = modes['verified'].sku
|
||||
mode_info['verified_bulk_sku'] = modes['verified'].bulk_sku
|
||||
# if there is an expiration date, find out how long from now it is
|
||||
if modes['verified'].expiration_datetime:
|
||||
today = datetime.datetime.now(UTC).date()
|
||||
|
||||
@@ -84,11 +84,13 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
|
||||
# TODO Verify this is the best method to create CourseMode objects.
|
||||
# TODO Find/create constants for the modes.
|
||||
for mode in [CourseMode.HONOR, CourseMode.VERIFIED, CourseMode.AUDIT]:
|
||||
sku_string = uuid4().hex.decode('ascii')
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course.id,
|
||||
mode_slug=mode,
|
||||
mode_display_name=mode,
|
||||
sku=uuid4().hex.decode('ascii')
|
||||
sku=sku_string,
|
||||
bulk_sku='BULK-{}'.format(sku_string)
|
||||
)
|
||||
|
||||
# Ignore events fired from UserFactory creation
|
||||
@@ -268,8 +270,9 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
|
||||
|
||||
CourseMode.objects.filter(course_id=self.course.id).delete()
|
||||
mode = CourseMode.NO_ID_PROFESSIONAL_MODE
|
||||
sku_string = uuid4().hex.decode('ascii')
|
||||
CourseModeFactory.create(course_id=self.course.id, mode_slug=mode, mode_display_name=mode,
|
||||
sku=uuid4().hex.decode('ascii'))
|
||||
sku=sku_string, bulk_sku='BULK-{}'.format(sku_string))
|
||||
|
||||
with mock_create_basket(expect_called=False):
|
||||
response = self._post_to_view()
|
||||
|
||||
@@ -87,6 +87,7 @@ class Course(object):
|
||||
merged_mode.min_price = posted_mode.min_price
|
||||
merged_mode.currency = posted_mode.currency
|
||||
merged_mode.sku = posted_mode.sku
|
||||
merged_mode.bulk_sku = posted_mode.bulk_sku
|
||||
merged_mode.expiration_datetime = posted_mode.expiration_datetime
|
||||
merged_mode.save()
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class CourseModeSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta(object):
|
||||
model = CourseMode
|
||||
fields = ('name', 'currency', 'price', 'sku', 'expires')
|
||||
fields = ('name', 'currency', 'price', 'sku', 'bulk_sku', 'expires')
|
||||
|
||||
|
||||
def validate_course_id(course_id):
|
||||
|
||||
@@ -37,8 +37,14 @@ class CourseApiViewTestMixin(object):
|
||||
def setUp(self):
|
||||
super(CourseApiViewTestMixin, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.course_mode = CourseMode.objects.create(course_id=self.course.id, mode_slug=u'verified', min_price=100,
|
||||
currency=u'USD', sku=u'ABC123')
|
||||
self.course_mode = CourseMode.objects.create(
|
||||
course_id=self.course.id,
|
||||
mode_slug=u'verified',
|
||||
min_price=100,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123'
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _serialize_datetime(cls, dt): # pylint: disable=invalid-name
|
||||
@@ -58,6 +64,7 @@ class CourseApiViewTestMixin(object):
|
||||
u'currency': course_mode.currency.lower(),
|
||||
u'price': course_mode.min_price,
|
||||
u'sku': course_mode.sku,
|
||||
u'bulk_sku': course_mode.bulk_sku,
|
||||
u'expires': cls._serialize_datetime(course_mode.expiration_datetime),
|
||||
}
|
||||
|
||||
@@ -147,6 +154,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
min_price=200,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123',
|
||||
expiration_datetime=mode_expiration
|
||||
)
|
||||
expected = self._serialize_course(self.course, [expected_course_mode], verification_deadline)
|
||||
@@ -217,6 +225,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
min_price=200,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123',
|
||||
expiration_datetime=None
|
||||
)
|
||||
updated_data = self._serialize_course(self.course, [verified_mode], None)
|
||||
@@ -251,7 +260,13 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
""" Verify that data submitted via PUT overwrites/deletes modes that are
|
||||
not included in the body of the request. """
|
||||
course_id = unicode(self.course.id)
|
||||
expected_course_mode = CourseMode(mode_slug=u'credit', min_price=500, currency=u'USD', sku=u'ABC123')
|
||||
expected_course_mode = CourseMode(
|
||||
mode_slug=u'credit',
|
||||
min_price=500,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123'
|
||||
)
|
||||
expected = self._serialize_course(self.course, [expected_course_mode])
|
||||
path = reverse('commerce_api:v1:courses:retrieve_update', args=[course_id])
|
||||
response = self.client.put(path, json.dumps(expected), content_type=JSON_CONTENT_TYPE)
|
||||
@@ -276,6 +291,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
min_price=500,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123',
|
||||
expiration_datetime=expiration_datetime
|
||||
)
|
||||
)
|
||||
@@ -290,8 +306,22 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
def assert_can_create_course(self, **request_kwargs):
|
||||
""" Verify a course can be created by the view. """
|
||||
course = CourseFactory.create()
|
||||
expected_modes = [CourseMode(mode_slug=u'verified', min_price=150, currency=u'USD', sku=u'ABC123'),
|
||||
CourseMode(mode_slug=u'honor', min_price=0, currency=u'USD', sku=u'DEADBEEF')]
|
||||
expected_modes = [
|
||||
CourseMode(
|
||||
mode_slug=u'verified',
|
||||
min_price=150,
|
||||
currency=u'USD',
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123'
|
||||
),
|
||||
CourseMode(
|
||||
mode_slug=u'honor',
|
||||
min_price=0,
|
||||
currency=u'USD',
|
||||
sku=u'DEADBEEF',
|
||||
bulk_sku=u'BULK-DEADBEEF'
|
||||
)
|
||||
]
|
||||
expected = self._serialize_course(course, expected_modes)
|
||||
path = reverse('commerce_api:v1:courses:retrieve_update', args=[unicode(course.id)])
|
||||
|
||||
@@ -331,7 +361,8 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
|
||||
CourseMode(
|
||||
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
|
||||
min_price=150, currency=u'USD',
|
||||
sku=u'ABC123'
|
||||
sku=u'ABC123',
|
||||
bulk_sku=u'BULK-ABC123'
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ class EcommerceServiceTests(TestCase):
|
||||
|
||||
@patch('openedx.core.djangoapps.theming.helpers.is_request_in_themed_site')
|
||||
def test_is_enabled_for_microsites(self, is_microsite):
|
||||
"""Verify that is_enabled() returns False if used for a microsite."""
|
||||
"""Verify that is_enabled() returns True if used for a microsite."""
|
||||
is_microsite.return_value = True
|
||||
is_not_enabled = EcommerceService().is_enabled(self.user)
|
||||
self.assertFalse(is_not_enabled)
|
||||
is_enabled = EcommerceService().is_enabled(self.user)
|
||||
self.assertTrue(is_enabled)
|
||||
|
||||
@override_settings(ECOMMERCE_PUBLIC_URL_ROOT='http://ecommerce_url')
|
||||
def test_payment_page_url(self):
|
||||
|
||||
@@ -45,9 +45,10 @@ class EcommerceService(object):
|
||||
self.config = CommerceConfiguration.current()
|
||||
|
||||
def is_enabled(self, user):
|
||||
""" Check if the user is activated, if the service is enabled and that the site is not a microsite. """
|
||||
return (user.is_active and self.config.checkout_on_ecommerce_service and not
|
||||
helpers.is_request_in_themed_site())
|
||||
"""
|
||||
Determines the availability of the Ecommerce service based on user activation and service configuration.
|
||||
"""
|
||||
return user.is_active and self.config.checkout_on_ecommerce_service
|
||||
|
||||
def payment_page_url(self):
|
||||
""" Return the URL for the checkout page.
|
||||
|
||||
@@ -10,6 +10,7 @@ from microsite_configuration import microsite
|
||||
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
|
||||
from shoppingcart.processors.CyberSource2 import is_user_payment_error
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangoapps.theming.helpers import is_request_in_themed_site
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -75,5 +76,6 @@ def checkout_receipt(request):
|
||||
'payment_support_email': payment_support_email,
|
||||
'username': request.user.username,
|
||||
'nav_hidden': True,
|
||||
'is_request_in_themed_site': is_request_in_themed_site()
|
||||
}
|
||||
return render_to_response('commerce/checkout_receipt.html', context)
|
||||
|
||||
@@ -512,7 +512,8 @@ def course_about(request, course_id):
|
||||
# professional or no id professional, we construct links for the enrollment
|
||||
# button to add the course to the ecommerce basket.
|
||||
ecommerce_checkout_link = ''
|
||||
professional_mode = ''
|
||||
ecommerce_bulk_checkout_link = ''
|
||||
professional_mode = None
|
||||
ecomm_service = EcommerceService()
|
||||
if ecomm_service.is_enabled(request.user) and (
|
||||
CourseMode.PROFESSIONAL in modes or CourseMode.NO_ID_PROFESSIONAL_MODE in modes
|
||||
@@ -520,7 +521,8 @@ def course_about(request, course_id):
|
||||
professional_mode = modes.get(CourseMode.PROFESSIONAL, '') or \
|
||||
modes.get(CourseMode.NO_ID_PROFESSIONAL_MODE, '')
|
||||
ecommerce_checkout_link = ecomm_service.checkout_page_url(professional_mode.sku)
|
||||
|
||||
if professional_mode.bulk_sku:
|
||||
ecommerce_bulk_checkout_link = ecomm_service.checkout_page_url(professional_mode.bulk_sku)
|
||||
course_price = get_cosmetic_display_price(course, registration_price)
|
||||
can_add_course_to_cart = _is_shopping_cart_enabled and registration_price
|
||||
|
||||
@@ -555,6 +557,7 @@ def course_about(request, course_id):
|
||||
'in_cart': in_cart,
|
||||
'ecommerce_checkout': ecomm_service.is_enabled(request.user),
|
||||
'ecommerce_checkout_link': ecommerce_checkout_link,
|
||||
'ecommerce_bulk_checkout_link': ecommerce_bulk_checkout_link,
|
||||
'professional_mode': professional_mode,
|
||||
'reg_then_add_to_cart_link': reg_then_add_to_cart_link,
|
||||
'show_courseware_link': show_courseware_link,
|
||||
|
||||
@@ -31,7 +31,8 @@ var edx = edx || {};
|
||||
var templateHtml = $("#receipt-tpl").html(),
|
||||
context = {
|
||||
platformName: this.$el.data('platform-name'),
|
||||
verified: this.$el.data('verified').toLowerCase() === 'true'
|
||||
verified: this.$el.data('verified').toLowerCase() === 'true',
|
||||
is_request_in_themed_site: this.$el.data('is-request-in-themed-site').toLowerCase() === 'true'
|
||||
},
|
||||
providerId;
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ from django.utils.translation import ugettext as _
|
||||
<div class="container">
|
||||
<section class="wrapper carousel">
|
||||
<div id="receipt-container" class="pay-and-verify hidden" data-is-payment-complete='${is_payment_complete}'
|
||||
data-platform-name='${platform_name}' data-verified='${verified}' data-username='${username}'>
|
||||
data-platform-name='${platform_name}' data-verified='${verified}' data-username='${username}'
|
||||
data-is-request-in-themed-site='${is_request_in_themed_site}'>
|
||||
<h1>${_("Loading Order Data...")}</h1>
|
||||
<span>${ _("Please wait while we retrieve your order details.") }</span>
|
||||
</div>
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<% } %>
|
||||
|
||||
<nav class="nav-wizard is-ready">
|
||||
<% if ( verified ) { %>
|
||||
<% if ( verified || is_request_in_themed_site) { %>
|
||||
<a class="next action-primary right" href="/dashboard"><%- gettext( "Go to Dashboard" ) %></a>
|
||||
<% } else { %>
|
||||
<a id="verify_later_button" class="next action-secondary verify-later nav-link" href="/dashboard" data-tooltip="<%- _.sprintf( gettext( "If you don't verify your identity now, you can still explore your course from your dashboard. You will receive periodic reminders from %(platformName)s to verify your identity." ), { platformName: platformName } ) %>">
|
||||
|
||||
Reference in New Issue
Block a user