Remove items from the shopping cart if they are for a course whose course enrollment window has closed
changed the url name to verify_cart and change the color of the message in the shopping cart
This commit is contained in:
@@ -769,6 +769,17 @@ class CourseEnrollment(models.Model):
|
||||
|
||||
return enrollment_number
|
||||
|
||||
@classmethod
|
||||
def is_enrollment_closed(cls, user, course):
|
||||
"""
|
||||
Returns a boolean value regarding whether the user has access to enroll in the course. Returns False if the
|
||||
enrollment has been closed.
|
||||
"""
|
||||
# Disable the pylint error here, as per ormsbee. This local import was previously
|
||||
# in CourseEnrollment.enroll
|
||||
from courseware.access import has_access # pylint: disable=import-error
|
||||
return not has_access(user, 'enroll', course)
|
||||
|
||||
@classmethod
|
||||
def is_course_full(cls, course):
|
||||
"""
|
||||
@@ -904,8 +915,6 @@ class CourseEnrollment(models.Model):
|
||||
|
||||
Also emits relevant events for analytics purposes.
|
||||
"""
|
||||
from courseware.access import has_access
|
||||
|
||||
# All the server-side checks for whether a user is allowed to enroll.
|
||||
try:
|
||||
course = modulestore().get_course(course_key)
|
||||
@@ -921,7 +930,7 @@ class CourseEnrollment(models.Model):
|
||||
if check_access:
|
||||
if course is None:
|
||||
raise NonExistentCourseError
|
||||
if not has_access(user, 'enroll', course):
|
||||
if CourseEnrollment.is_enrollment_closed(user, course):
|
||||
log.warning(
|
||||
"User {0} failed to enroll in course {1} because enrollment is closed".format(
|
||||
user.username,
|
||||
|
||||
@@ -152,6 +152,15 @@ class Order(models.Model):
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def remove_cart_item_from_order(cls, item):
|
||||
"""
|
||||
Removes the item from the cart if the item.order.status == 'cart'.
|
||||
"""
|
||||
if item.order.status == 'cart':
|
||||
log.info("Item {0} removed from the user cart".format(item.id))
|
||||
item.delete()
|
||||
|
||||
@property
|
||||
def total_cost(self):
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Tests for Shopping Cart views
|
||||
"""
|
||||
import pytz
|
||||
from urlparse import urlparse
|
||||
|
||||
from django.http import HttpRequest
|
||||
@@ -1102,6 +1103,120 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
self._assert_404(reverse('shoppingcart.views.register_courses', args=[]))
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=MODULESTORE_CONFIG)
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
|
||||
"""
|
||||
Test suite for ShoppingcartViews Course Enrollments Closed or not
|
||||
"""
|
||||
def setUp(self):
|
||||
|
||||
super(ShoppingcartViewsClosedEnrollment, self).setUp()
|
||||
self.user = UserFactory.create()
|
||||
self.user.set_password('password')
|
||||
self.user.save()
|
||||
self.instructor = AdminFactory.create()
|
||||
self.cost = 40
|
||||
|
||||
self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
|
||||
self.course_key = self.course.id
|
||||
self.course_mode = CourseMode(course_id=self.course_key,
|
||||
mode_slug="honor",
|
||||
mode_display_name="honor cert",
|
||||
min_price=self.cost)
|
||||
self.course_mode.save()
|
||||
self.testing_course = CourseFactory.create(
|
||||
org='Edx',
|
||||
number='999',
|
||||
display_name='Testing Super Course',
|
||||
metadata={"invitation_only": False}
|
||||
)
|
||||
self.course_mode = CourseMode(course_id=self.testing_course.id,
|
||||
mode_slug="honor",
|
||||
mode_display_name="honor cert",
|
||||
min_price=self.cost)
|
||||
self.course_mode.save()
|
||||
self.cart = Order.get_cart_for_user(self.user)
|
||||
self.now = datetime.now(pytz.UTC)
|
||||
self.tomorrow = self.now + timedelta(days=1)
|
||||
self.nextday = self.tomorrow + timedelta(days=1)
|
||||
|
||||
def login_user(self):
|
||||
"""
|
||||
Helper fn to login self.user
|
||||
"""
|
||||
self.client.login(username=self.user.username, password="password")
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_to_check_that_cart_item_enrollment_is_closed(self):
|
||||
self.login_user()
|
||||
reg_item1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.testing_course.id)
|
||||
|
||||
# update the testing_course enrollment dates
|
||||
self.testing_course.enrollment_start = self.tomorrow
|
||||
self.testing_course.enrollment_end = self.nextday
|
||||
self.testing_course = self.update_course(self.testing_course, self.user.id)
|
||||
|
||||
# testing_course enrollment is closed but the course is in the cart
|
||||
# so we delete that item from the cart and display the message in the cart
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn("{course_name} has been removed because the enrollment period has closed.".format(course_name=self.testing_course.display_name), resp.content)
|
||||
|
||||
((template, context), _tmp) = render_mock.call_args
|
||||
self.assertEqual(template, 'shoppingcart/shopping_cart.html')
|
||||
self.assertEqual(context['order'], self.cart)
|
||||
self.assertIn(reg_item1, context['shoppingcart_items'][0])
|
||||
self.assertEqual(1, len(context['shoppingcart_items']))
|
||||
self.assertEqual(True, context['is_course_enrollment_closed'])
|
||||
self.assertIn(self.testing_course.display_name, context['appended_expired_course_names'])
|
||||
|
||||
def test_to_check_that_cart_item_enrollment_is_closed_when_clicking_the_payment_button(self):
|
||||
self.login_user()
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.testing_course.id)
|
||||
|
||||
# update the testing_course enrollment dates
|
||||
self.testing_course.enrollment_start = self.tomorrow
|
||||
self.testing_course.enrollment_end = self.nextday
|
||||
self.testing_course = self.update_course(self.testing_course, self.user.id)
|
||||
|
||||
# testing_course enrollment is closed but the course is in the cart
|
||||
# so we delete that item from the cart and display the message in the cart
|
||||
resp = self.client.get(reverse('shoppingcart.views.verify_cart'))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertTrue(json.loads(resp.content)['is_course_enrollment_closed'])
|
||||
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn("{course_name} has been removed because the enrollment period has closed.".format(course_name=self.testing_course.display_name), resp.content)
|
||||
self.assertIn('40.00', resp.content)
|
||||
|
||||
def test_is_enrollment_closed_when_order_type_is_business(self):
|
||||
self.login_user()
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.testing_course.id, 2)
|
||||
|
||||
# update the testing_course enrollment dates
|
||||
self.testing_course.enrollment_start = self.tomorrow
|
||||
self.testing_course.enrollment_end = self.nextday
|
||||
self.testing_course = self.update_course(self.testing_course, self.user.id)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.billing_details'))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertTrue(json.loads(resp.content)['is_course_enrollment_closed'])
|
||||
|
||||
# testing_course enrollment is closed but the course is in the cart
|
||||
# so we delete that item from the cart and display the message in the cart
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn("{course_name} has been removed because the enrollment period has closed.".format(course_name=self.testing_course.display_name), resp.content)
|
||||
self.assertIn('40.00', resp.content)
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=MODULESTORE_CONFIG)
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
class RegistrationCodeRedemptionCourseEnrollment(ModuleStoreTestCase):
|
||||
|
||||
@@ -16,6 +16,7 @@ urlpatterns = patterns('shoppingcart.views', # nopep8
|
||||
url(r'^update_user_cart/$', 'update_user_cart'),
|
||||
url(r'^reset_code_redemption/$', 'reset_code_redemption'),
|
||||
url(r'^billing_details/$', 'billing_details', name='billing_details'),
|
||||
url(r'^verify_cart/$', 'verify_cart'),
|
||||
url(r'^register_courses/$', 'register_courses'),
|
||||
)
|
||||
|
||||
|
||||
@@ -148,25 +148,27 @@ def show_cart(request):
|
||||
This view shows cart items.
|
||||
"""
|
||||
cart = Order.get_cart_for_user(request.user)
|
||||
total_cost = cart.total_cost
|
||||
cart_items = cart.orderitem_set.all().select_subclasses()
|
||||
shoppingcart_items = []
|
||||
for cart_item in cart_items:
|
||||
course_key = getattr(cart_item, 'course_id')
|
||||
if course_key:
|
||||
course = get_course_by_id(course_key, depth=0)
|
||||
shoppingcart_items.append((cart_item, course))
|
||||
|
||||
is_any_course_expired, expired_cart_items, expired_cart_item_names, valid_cart_item_tuples = \
|
||||
verify_for_closed_enrollment(request.user, cart)
|
||||
site_name = microsite.get_value('SITE_NAME', settings.SITE_NAME)
|
||||
|
||||
if is_any_course_expired:
|
||||
for expired_item in expired_cart_items:
|
||||
Order.remove_cart_item_from_order(expired_item)
|
||||
cart.update_order_type()
|
||||
|
||||
appended_expired_course_names = ", ".join(expired_cart_item_names)
|
||||
|
||||
callback_url = request.build_absolute_uri(
|
||||
reverse("shoppingcart.views.postpay_callback")
|
||||
)
|
||||
form_html = render_purchase_form_html(cart, callback_url=callback_url)
|
||||
context = {
|
||||
'order': cart,
|
||||
'shoppingcart_items': shoppingcart_items,
|
||||
'amount': total_cost,
|
||||
'shoppingcart_items': valid_cart_item_tuples,
|
||||
'amount': cart.total_cost,
|
||||
'is_course_enrollment_closed': is_any_course_expired,
|
||||
'appended_expired_course_names': appended_expired_course_names,
|
||||
'site_name': site_name,
|
||||
'form_html': form_html,
|
||||
'currency_symbol': settings.PAID_COURSE_REGISTRATION_CURRENCY[1],
|
||||
@@ -559,8 +561,7 @@ def billing_details(request):
|
||||
"""
|
||||
|
||||
cart = Order.get_cart_for_user(request.user)
|
||||
cart_items = cart.orderitem_set.all()
|
||||
|
||||
cart_items = cart.orderitem_set.all().select_subclasses()
|
||||
if getattr(cart, 'order_type') != OrderTypes.BUSINESS:
|
||||
raise Http404('Page not found!')
|
||||
|
||||
@@ -589,11 +590,65 @@ def billing_details(request):
|
||||
|
||||
cart.add_billing_details(company_name, company_contact_name, company_contact_email, recipient_name,
|
||||
recipient_email, customer_reference_number)
|
||||
|
||||
is_any_course_expired, __, __, __ = verify_for_closed_enrollment(request.user)
|
||||
|
||||
return JsonResponse({
|
||||
'response': _('success')
|
||||
'response': _('success'),
|
||||
'is_course_enrollment_closed': is_any_course_expired
|
||||
}) # status code 200: OK by default
|
||||
|
||||
|
||||
def verify_for_closed_enrollment(user, cart=None):
|
||||
"""
|
||||
A multi-output helper function.
|
||||
inputs:
|
||||
user: a user object
|
||||
cart: If a cart is provided it uses the same object, otherwise fetches the user's cart.
|
||||
Returns:
|
||||
is_any_course_expired: True if any of the items in the cart has it's enrollment period closed. False otherwise.
|
||||
expired_cart_items: List of courses with enrollment period closed.
|
||||
expired_cart_item_names: List of names of the courses with enrollment period closed.
|
||||
valid_cart_item_tuples: List of courses which are still open for enrollment.
|
||||
"""
|
||||
if cart is None:
|
||||
cart = Order.get_cart_for_user(user)
|
||||
expired_cart_items = []
|
||||
expired_cart_item_names = []
|
||||
valid_cart_item_tuples = []
|
||||
cart_items = cart.orderitem_set.all().select_subclasses()
|
||||
is_any_course_expired = False
|
||||
for cart_item in cart_items:
|
||||
course_key = getattr(cart_item, 'course_id', None)
|
||||
if course_key is not None:
|
||||
course = get_course_by_id(course_key, depth=0)
|
||||
if CourseEnrollment.is_enrollment_closed(user, course):
|
||||
is_any_course_expired = True
|
||||
expired_cart_items.append(cart_item)
|
||||
expired_cart_item_names.append(course.display_name)
|
||||
else:
|
||||
valid_cart_item_tuples.append((cart_item, course))
|
||||
|
||||
return is_any_course_expired, expired_cart_items, expired_cart_item_names, valid_cart_item_tuples
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
@login_required
|
||||
@enforce_shopping_cart_enabled
|
||||
def verify_cart(request):
|
||||
"""
|
||||
Called when the user clicks the button to transfer control to CyberSource.
|
||||
Returns a JSON response with is_course_enrollment_closed set to True if any of the courses has its
|
||||
enrollment period closed. If all courses are still valid, is_course_enrollment_closed set to False.
|
||||
"""
|
||||
is_any_course_expired, __, __, __ = verify_for_closed_enrollment(request.user)
|
||||
return JsonResponse(
|
||||
{
|
||||
'is_course_enrollment_closed': is_any_course_expired
|
||||
}
|
||||
) # status code 200: OK by default
|
||||
|
||||
|
||||
@login_required
|
||||
def show_receipt(request, ordernum):
|
||||
"""
|
||||
|
||||
126
lms/static/js/shoppingcart/shoppingcart.js
Normal file
126
lms/static/js/shoppingcart/shoppingcart.js
Normal file
@@ -0,0 +1,126 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
edx.shoppingcart = edx.shoppingcart || {};
|
||||
edx.shoppingcart.showcart = {};
|
||||
|
||||
/**
|
||||
* View for making shoppingcart
|
||||
* @constructor
|
||||
* @param {Object} params
|
||||
* @param {Object} params.el - The payment form element.
|
||||
*/
|
||||
edx.shoppingcart.showcart.CartView = function(params) {
|
||||
/**
|
||||
* cart view that checks that all the cart items are valid (course enrollment is closed or not)
|
||||
* before the form submitted to the payment processor.
|
||||
* @param {Object} form - The form to modify.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check for all the cart items are still valid (courses enrollment are not closed)
|
||||
*
|
||||
* @returns {Object} The promise from the AJAX call to the server,
|
||||
* which checks for cart items are valid or not and returns the boolean
|
||||
* { is_course_enrollment_closed: <boolead> }
|
||||
*/
|
||||
var isCourseEnrollmentAllowed = function() {
|
||||
return $.ajax({
|
||||
url: "/shoppingcart/verify_cart/",
|
||||
type: "GET"
|
||||
});
|
||||
};
|
||||
|
||||
var view = {
|
||||
/**
|
||||
* Initialize the view.
|
||||
*
|
||||
* @param {Object} params
|
||||
* @param {JQuery selector} params.el - The payment form element.
|
||||
* @returns {CartView}
|
||||
*/
|
||||
initialize: function(params) {
|
||||
this.$el = params.el;
|
||||
_.bindAll(view,
|
||||
'submit', 'responseFromServer',
|
||||
'submitPaymentForm', 'errorFromServer'
|
||||
);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a click event on the "payment form submit" button.
|
||||
* This will contact the LMS server to check for all the
|
||||
* valid cart items (courses enrollment should not be closed at this point)
|
||||
* then send the user to the external payment processor or redirects to the
|
||||
* dashboard page
|
||||
*
|
||||
* @param {Object} event - The click event.
|
||||
*/
|
||||
submit: function(event) {
|
||||
// Prevent form submission
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// Immediately disable the submit button to prevent duplicate submissions
|
||||
this.$el.find('input[type="submit"]').addClass("disabled");
|
||||
|
||||
this.$paymentForm = this.$el;
|
||||
isCourseEnrollmentAllowed()
|
||||
.done(this.responseFromServer)
|
||||
.fail(this.errorFromServer);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send signed payment parameters to the external
|
||||
* payment processor if cart items are valid else redirect to
|
||||
* shoppingcart.
|
||||
*
|
||||
* @param {boolean} data.is_course_enrollment_closed
|
||||
*/
|
||||
responseFromServer: function(data) {
|
||||
if (data.is_course_enrollment_closed == true) {
|
||||
location.href = "/shoppingcart";
|
||||
}
|
||||
else {
|
||||
this.submitPaymentForm(this.$paymentForm);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* In case the server responded back with errors
|
||||
*
|
||||
*/
|
||||
errorFromServer: function() {
|
||||
// Immediately enable the submit button to allow submission
|
||||
this.$el.find('input[type="submit"]').removeClass("disabled");
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit the payment from to the external payment processor.
|
||||
*
|
||||
* @param {Object} form
|
||||
*/
|
||||
submitPaymentForm: function(form) {
|
||||
form.submit();
|
||||
}
|
||||
};
|
||||
|
||||
view.initialize(params);
|
||||
return view;
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
// (click on the payment submit button).
|
||||
$('.cart-view form input[type="submit"]').click(function(event) {
|
||||
var container = $('.confirm-enrollment.cart-view form');
|
||||
var view = new edx.shoppingcart.showcart.CartView({
|
||||
el:container
|
||||
}).submit(event);
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -261,6 +261,10 @@
|
||||
exports: 'js/dashboard/donation',
|
||||
deps: ['jquery', 'underscore', 'gettext']
|
||||
},
|
||||
'js/shoppingcart/shoppingcart.js': {
|
||||
exports: 'js/shoppingcart/shoppingcart',
|
||||
deps: ['jquery', 'underscore', 'gettext']
|
||||
},
|
||||
|
||||
// Backbone classes loaded explicitly until they are converted to use RequireJS
|
||||
'js/models/cohort': {
|
||||
@@ -382,6 +386,7 @@
|
||||
'lms/include/js/spec/staff_debug_actions_spec.js',
|
||||
'lms/include/js/spec/views/notification_spec.js',
|
||||
'lms/include/js/spec/dashboard/donation.js',
|
||||
'lms/include/js/spec/shoppingcart/shoppingcart_spec.js',
|
||||
'lms/include/js/spec/student_account/account_spec.js',
|
||||
'lms/include/js/spec/student_account/access_spec.js',
|
||||
'lms/include/js/spec/student_account/login_spec.js',
|
||||
|
||||
59
lms/static/js/spec/shoppingcart/shoppingcart_spec.js
Normal file
59
lms/static/js/spec/shoppingcart/shoppingcart_spec.js
Normal file
@@ -0,0 +1,59 @@
|
||||
define(['js/common_helpers/ajax_helpers', 'js/shoppingcart/shoppingcart'],
|
||||
function(AjaxHelpers) {
|
||||
'use strict';
|
||||
|
||||
describe("edx.shoppingcart.showcart.CartView", function() {
|
||||
var view = null;
|
||||
var requests = null;
|
||||
|
||||
beforeEach(function() {
|
||||
setFixtures('<section class="wrapper confirm-enrollment shopping-cart cart-view"><form action="" method="post"><input type="hidden" name="" value="" /><i class="icon-caret-right"></i><input type="submit" value="Payment"/></form></section>');
|
||||
|
||||
view = new edx.shoppingcart.showcart.CartView({
|
||||
el: $('.confirm-enrollment.cart-view form')
|
||||
});
|
||||
|
||||
spyOn(view, 'responseFromServer').andCallFake(function() {});
|
||||
|
||||
// Spy on AJAX requests
|
||||
requests = AjaxHelpers.requests(this);
|
||||
|
||||
view.submit();
|
||||
|
||||
// Verify that the client contacts the server to
|
||||
// check for all th valid cart items
|
||||
AjaxHelpers.expectRequest(
|
||||
requests, "GET", "/shoppingcart/verify_cart/"
|
||||
);
|
||||
});
|
||||
|
||||
it("cart has invalid items, course enrollment has been closed", function() {
|
||||
// Simulate a response from the server containing the
|
||||
// parameter 'is_course_enrollment_closed'. This decides that
|
||||
// do we have all the cart items valid in the cart or not
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
is_course_enrollment_closed: true
|
||||
});
|
||||
|
||||
expect(view.responseFromServer).toHaveBeenCalled();
|
||||
var data = view.responseFromServer.mostRecentCall.args[0]
|
||||
expect(data.is_course_enrollment_closed).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it("cart has all valid items, course enrollment is still open", function() {
|
||||
// Simulate a response from the server containing the
|
||||
// parameter 'is_course_enrollment_closed'. This decides that
|
||||
// do we have all the cart items valid in the cart or not
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
is_course_enrollment_closed: false
|
||||
});
|
||||
|
||||
expect(view.responseFromServer).toHaveBeenCalled();
|
||||
var data = view.responseFromServer.mostRecentCall.args[0]
|
||||
expect(data.is_course_enrollment_closed).toBe(false);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -171,6 +171,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#expiry-msg {
|
||||
padding: 15px;
|
||||
background-color: #f2f2f2;
|
||||
margin-top: 3px;
|
||||
font-family: $sans-serif;
|
||||
font-size: 14px;
|
||||
text-shadow: 0px 1px 1px #fff;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
.confirm-enrollment {
|
||||
.title {
|
||||
font-size:24px;
|
||||
@@ -885,6 +894,14 @@
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
text-transform: initial;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
font-family: $sans-serif;
|
||||
color: #9d9d9d;
|
||||
text-align: center;
|
||||
text-shadow: 0px 1px 1px #fff;
|
||||
}
|
||||
a.blue{
|
||||
display: inline-block;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<%block name="custom_content">
|
||||
<div class="container">
|
||||
% if shoppingcart_items:
|
||||
<section class="confirm-enrollment shopping-cart">
|
||||
<section class="confirm-enrollment shopping-cart billing-details-view">
|
||||
<h3>${_('You can proceed to payment at any point in time. Any additional information you provide will be included in your receipt.')}</h3>
|
||||
<div class="billing-data">
|
||||
<div class="col-half">
|
||||
@@ -93,6 +93,8 @@
|
||||
return false;
|
||||
}
|
||||
event.preventDefault();
|
||||
// Disable the submit button to prevent duplicate submissions
|
||||
$(this).addClass("disabled");
|
||||
var post_url = "${reverse('billing_details')}";
|
||||
var data = {
|
||||
"company_name" : $('input[name="company_name"]').val(),
|
||||
@@ -104,10 +106,15 @@
|
||||
};
|
||||
$.post(post_url, data)
|
||||
.success(function(data) {
|
||||
payment_form.submit();
|
||||
})
|
||||
if (data.is_course_enrollment_closed == true) {
|
||||
location.href = "${reverse('shoppingcart.views.show_cart')}";
|
||||
}
|
||||
else {
|
||||
payment_form.submit();
|
||||
}
|
||||
})
|
||||
.error(function(data,status) {
|
||||
|
||||
$(this).removeClass("disabled");
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,13 +21,15 @@ from django.utils.translation import ugettext as _
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
% if is_course_enrollment_closed:
|
||||
<p id="expiry-msg">${_('{course_names} has been removed because the enrollment period has closed.').format(course_names=appended_expired_course_names)}</p>
|
||||
% endif:
|
||||
<%
|
||||
discount_applied = False
|
||||
order_type = 'personal'
|
||||
%>
|
||||
|
||||
|
||||
<section class="wrapper confirm-enrollment shopping-cart">
|
||||
<section class="wrapper confirm-enrollment shopping-cart cart-view">
|
||||
% for item, course in shoppingcart_items:
|
||||
% if loop.index > 0 :
|
||||
<hr>
|
||||
@@ -135,7 +137,10 @@ from django.utils.translation import ugettext as _
|
||||
% else:
|
||||
<div class="empty-cart" >
|
||||
<h2>${_('Your Shopping cart is currently empty.')}</h2>
|
||||
<a href="${marketing_link('COURSES')}" class="blue">${_('View Courses')}</a>
|
||||
% if is_course_enrollment_closed:
|
||||
<p>${_('{course_names} has been removed because the enrollment period has closed.').format(course_names=appended_expired_course_names)}</p>
|
||||
% endif
|
||||
<a href="${marketing_link('COURSES')}" class="blue">${_('View Courses')}</a>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
@@ -146,7 +151,7 @@ from django.utils.translation import ugettext as _
|
||||
var isSpinnerBtnEnabled = true;
|
||||
var prevQty = 0;
|
||||
|
||||
$('a.btn-remove').click(function(event) {
|
||||
$('a.btn-remove').click(function(event) {
|
||||
event.preventDefault();
|
||||
var post_url = "${reverse('shoppingcart.views.remove_item')}";
|
||||
$.post(post_url, {id:$(this).data('item-id')})
|
||||
|
||||
@@ -4,10 +4,11 @@ from django.utils.translation import ugettext as _
|
||||
<%inherit file="../main.html" />
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
<%block name="pagetitle">${_("Shopping cart")}</%block>
|
||||
|
||||
<%! from django.conf import settings %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%block name="headextra">
|
||||
<script type="text/javascript" src="${static.url('js/shoppingcart/shoppingcart.js')}"></script>
|
||||
</%block>
|
||||
<%block name="bodyextra">
|
||||
|
||||
<div class="container">
|
||||
|
||||
Reference in New Issue
Block a user