EX-81 / Ex-84 changes
This commit is contained in:
@@ -9,6 +9,7 @@ from django.utils.translation import ugettext as _
|
||||
from util.json_request import JsonResponse
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from shoppingcart.models import Coupon, CourseRegistrationCode
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
import logging
|
||||
|
||||
@@ -54,32 +55,34 @@ def add_coupon(request, course_id): # pylint: disable=W0613
|
||||
code = request.POST.get('code')
|
||||
|
||||
# check if the code is already in the Coupons Table and active
|
||||
coupon = Coupon.objects.filter(is_active=True, code=code)
|
||||
try:
|
||||
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
coupon = Coupon.objects.get(is_active=True, code=code, course_id=course_id)
|
||||
except Coupon.DoesNotExist:
|
||||
# check if the coupon code is in the CourseRegistrationCode Table
|
||||
course_registration_code = CourseRegistrationCode.objects.filter(code=code)
|
||||
if course_registration_code:
|
||||
return HttpResponseNotFound(_(
|
||||
"The code ({code}) that you have tried to define is already in use as a registration code").format(code=code)
|
||||
)
|
||||
|
||||
description = request.POST.get('description')
|
||||
course_id = request.POST.get('course_id')
|
||||
try:
|
||||
discount = int(request.POST.get('discount'))
|
||||
except ValueError:
|
||||
return HttpResponseNotFound(_("Please Enter the Integer Value for Coupon Discount"))
|
||||
if discount > 100 or discount < 0:
|
||||
return HttpResponseNotFound(_("Please Enter the Coupon Discount Value Less than or Equal to 100"))
|
||||
coupon = Coupon(
|
||||
code=code, description=description, course_id=course_id,
|
||||
percentage_discount=discount, created_by_id=request.user.id
|
||||
)
|
||||
coupon.save()
|
||||
return HttpResponse(_("coupon with the coupon code ({code}) added successfully").format(code=code))
|
||||
|
||||
if coupon:
|
||||
return HttpResponseNotFound(_("coupon with the coupon code ({code}) already exist").format(code=code))
|
||||
|
||||
# check if the coupon code is in the CourseRegistrationCode Table
|
||||
course_registration_code = CourseRegistrationCode.objects.filter(code=code)
|
||||
if course_registration_code:
|
||||
return HttpResponseNotFound(_(
|
||||
"The code ({code}) that you have tried to define is already in use as a registration code").format(code=code)
|
||||
)
|
||||
|
||||
description = request.POST.get('description')
|
||||
course_id = request.POST.get('course_id')
|
||||
try:
|
||||
discount = int(request.POST.get('discount'))
|
||||
except ValueError:
|
||||
return HttpResponseNotFound(_("Please Enter the Integer Value for Coupon Discount"))
|
||||
if discount > 100:
|
||||
return HttpResponseNotFound(_("Please Enter the Coupon Discount Value Less than or Equal to 100"))
|
||||
coupon = Coupon(
|
||||
code=code, description=description, course_id=course_id,
|
||||
percentage_discount=discount, created_by_id=request.user.id
|
||||
)
|
||||
coupon.save()
|
||||
return HttpResponse(_("coupon with the coupon code ({code}) added successfully").format(code=code))
|
||||
return HttpResponseNotFound(_("coupon with the coupon code ({code}) already exists for this course").format(code=code))
|
||||
|
||||
|
||||
@require_POST
|
||||
|
||||
@@ -81,7 +81,7 @@ def purchase_transactions(course_id, features):
|
||||
]
|
||||
"""
|
||||
|
||||
purchased_courses = PaidCourseRegistration.objects.filter(course_id=course_id, status='purchased')
|
||||
purchased_courses = PaidCourseRegistration.objects.filter(course_id=course_id, status='purchased').order_by('user')
|
||||
|
||||
def purchase_transactions_info(purchased_course, features):
|
||||
""" convert purchase transactions to dictionary """
|
||||
@@ -103,12 +103,17 @@ def purchase_transactions(course_id, features):
|
||||
for feature in order_item_features)
|
||||
order_item_dict.update({"orderitem_id": getattr(purchased_course, 'id')})
|
||||
|
||||
try:
|
||||
coupon_redemption = CouponRedemption.objects.select_related('coupon').get(order_id=purchased_course.order_id)
|
||||
except CouponRedemption.DoesNotExist:
|
||||
coupon_code_dict = {'coupon_code': 'None'}
|
||||
coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(order_id=purchased_course.order_id)
|
||||
if coupon_redemption:
|
||||
# we format the coupon codes in comma separated way if there are more then one coupon against a order id.
|
||||
coupon_codes = list()
|
||||
for redemption in coupon_redemption:
|
||||
coupon_codes.append(redemption.coupon.code)
|
||||
|
||||
coupon_code_dict = {'coupon_code': ", ".join(coupon_codes)}
|
||||
|
||||
else:
|
||||
coupon_code_dict = {'coupon_code': coupon_redemption.coupon.code}
|
||||
coupon_code_dict = {'coupon_code': 'None'}
|
||||
|
||||
student_dict.update(dict(order_dict.items() + order_item_dict.items() + coupon_code_dict.items()))
|
||||
student_dict.update({'course_id': course_id.to_deprecated_string()})
|
||||
|
||||
@@ -32,11 +32,7 @@ class CouponDoesNotExistException(InvalidCartItem):
|
||||
pass
|
||||
|
||||
|
||||
class CouponAlreadyExistException(InvalidCartItem):
|
||||
pass
|
||||
|
||||
|
||||
class ItemDoesNotExistAgainstCouponException(InvalidCartItem):
|
||||
class MultipleCouponsNotAllowedException(InvalidCartItem):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ from verify_student.models import SoftwareSecurePhotoVerification
|
||||
|
||||
from .exceptions import (InvalidCartItem, PurchasedCallbackException, ItemAlreadyInCartException,
|
||||
AlreadyEnrolledInCourseException, CourseDoesNotExistException,
|
||||
CouponAlreadyExistException, ItemDoesNotExistAgainstCouponException,
|
||||
RegCodeAlreadyExistException, ItemDoesNotExistAgainstRegCodeException)
|
||||
MultipleCouponsNotAllowedException, RegCodeAlreadyExistException, ItemDoesNotExistAgainstRegCodeException)
|
||||
|
||||
from microsite_configuration import microsite
|
||||
|
||||
@@ -498,31 +497,33 @@ class CouponRedemption(models.Model):
|
||||
return value - discount
|
||||
|
||||
@classmethod
|
||||
def add_coupon_redemption(cls, coupon, order):
|
||||
def add_coupon_redemption(cls, coupon, order, cart_items):
|
||||
"""
|
||||
add coupon info into coupon_redemption model
|
||||
"""
|
||||
cart_items = order.orderitem_set.all().select_subclasses()
|
||||
is_redemption_applied = False
|
||||
coupon_redemptions = cls.objects.filter(order=order, user=order.user)
|
||||
for coupon_redemption in coupon_redemptions:
|
||||
if coupon_redemption.coupon.code != coupon.code or coupon_redemption.coupon.id == coupon.id:
|
||||
log.exception("Coupon redemption already exist for user '{0}' against order id '{1}'"
|
||||
.format(order.user.username, order.id))
|
||||
raise MultipleCouponsNotAllowedException
|
||||
|
||||
for item in cart_items:
|
||||
if getattr(item, 'course_id'):
|
||||
if item.course_id == coupon.course_id:
|
||||
coupon_redemption, created = cls.objects.get_or_create(order=order, user=order.user, coupon=coupon)
|
||||
if not created:
|
||||
log.exception("Coupon '{0}' already exist for user '{1}' against order id '{2}'"
|
||||
.format(coupon.code, order.user.username, order.id))
|
||||
raise CouponAlreadyExistException
|
||||
|
||||
coupon_redemption = cls(order=order, user=order.user, coupon=coupon)
|
||||
coupon_redemption.save()
|
||||
discount_price = cls.get_discount_price(coupon.percentage_discount, item.unit_cost)
|
||||
item.list_price = item.unit_cost
|
||||
item.unit_cost = discount_price
|
||||
item.save()
|
||||
log.info("Discount generated for user {0} against order id '{1}' "
|
||||
.format(order.user.username, order.id))
|
||||
return coupon_redemption
|
||||
is_redemption_applied = True
|
||||
return is_redemption_applied
|
||||
|
||||
log.warning("Course item does not exist for coupon '{0}'".format(coupon.code))
|
||||
raise ItemDoesNotExistAgainstCouponException
|
||||
return is_redemption_applied
|
||||
|
||||
|
||||
class PaidCourseRegistration(OrderItem):
|
||||
|
||||
@@ -77,18 +77,18 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
self.cart = Order.get_cart_for_user(self.user)
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
def get_discount(self):
|
||||
def get_discount(self, cost):
|
||||
"""
|
||||
This method simple return the discounted amount
|
||||
"""
|
||||
val = Decimal("{0:.2f}".format(Decimal(self.percentage_discount / 100.00) * self.cost))
|
||||
return self.cost - val
|
||||
val = Decimal("{0:.2f}".format(Decimal(self.percentage_discount / 100.00) * cost))
|
||||
return cost - val
|
||||
|
||||
def add_coupon(self, course_key, is_active):
|
||||
def add_coupon(self, course_key, is_active, code):
|
||||
"""
|
||||
add dummy coupon into models
|
||||
"""
|
||||
coupon = Coupon(code=self.coupon_code, description='testing code', course_id=course_key,
|
||||
coupon = Coupon(code=code, description='testing code', course_id=course_key,
|
||||
percentage_discount=self.percentage_discount, created_by=self.user, is_active=is_active)
|
||||
coupon.save()
|
||||
|
||||
@@ -99,12 +99,12 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
course_reg_code = CourseRegistrationCode(code=self.reg_code, course_id=course_key, created_by=self.user)
|
||||
course_reg_code.save()
|
||||
|
||||
def add_course_to_user_cart(self):
|
||||
def add_course_to_user_cart(self, course_key):
|
||||
"""
|
||||
adding course to user cart
|
||||
"""
|
||||
self.login_user()
|
||||
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
reg_item = PaidCourseRegistration.add_to_order(self.cart, course_key)
|
||||
return reg_item
|
||||
|
||||
def login_user(self):
|
||||
@@ -122,8 +122,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
self.assertIn('The course {0} is already in your cart.'.format(self.course_key.to_deprecated_string()), resp.content)
|
||||
|
||||
def test_course_discount_invalid_coupon(self):
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
non_existing_code = "non_existing_code"
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': non_existing_code})
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
@@ -131,23 +131,23 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
|
||||
def test_course_discount_invalid_reg_code(self):
|
||||
self.add_reg_code(self.course_key)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
non_existing_code = "non_existing_code"
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': non_existing_code})
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
self.assertIn("Discount does not exist against code '{0}'.".format(non_existing_code), resp.content)
|
||||
|
||||
def test_course_discount_inactive_coupon(self):
|
||||
self.add_coupon(self.course_key, False)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, False, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
self.assertIn("Discount does not exist against code '{0}'.".format(self.coupon_code), resp.content)
|
||||
|
||||
def test_course_does_not_exist_in_cart_against_valid_coupon(self):
|
||||
course_key = self.course_key.to_deprecated_string() + 'testing'
|
||||
self.add_coupon(course_key, True)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_coupon(course_key, True, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
@@ -156,7 +156,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
def test_course_does_not_exist_in_cart_against_valid_reg_code(self):
|
||||
course_key = self.course_key.to_deprecated_string() + 'testing'
|
||||
self.add_reg_code(course_key)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
@@ -164,26 +164,64 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
|
||||
def test_course_discount_for_valid_active_coupon_code(self):
|
||||
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# unit price should be updated for that course
|
||||
item = self.cart.orderitem_set.all().select_subclasses()[0]
|
||||
self.assertEquals(item.unit_cost, self.get_discount())
|
||||
self.assertEquals(item.unit_cost, self.get_discount(self.cost))
|
||||
|
||||
# after getting 10 percent discount
|
||||
self.assertEqual(self.cart.total_cost, self.get_discount())
|
||||
self.assertEqual(self.cart.total_cost, self.get_discount(self.cost))
|
||||
|
||||
# now testing coupon code already used scenario, reusing the same coupon code
|
||||
# now using the same coupon code against the same order.
|
||||
# Only one coupon redemption should be allowed per order.
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
self.assertIn("Coupon '{0}' already used.".format(self.coupon_code), resp.content)
|
||||
self.assertIn("Only one coupon redemption is allowed against an order", resp.content)
|
||||
|
||||
def test_course_discount_against_two_distinct_coupon_codes(self):
|
||||
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# unit price should be updated for that course
|
||||
item = self.cart.orderitem_set.all().select_subclasses()[0]
|
||||
self.assertEquals(item.unit_cost, self.get_discount(self.cost))
|
||||
|
||||
# now using another valid active coupon code.
|
||||
# Only one coupon redemption should be allowed per order.
|
||||
self.add_coupon(self.course_key, True, 'abxyz')
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': 'abxyz'})
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
self.assertIn("Only one coupon redemption is allowed against an order", resp.content)
|
||||
|
||||
def test_same_coupons_code_on_multiple_courses(self):
|
||||
|
||||
# add two same coupon codes on two different courses
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
self.add_coupon(self.testing_course.id, True, self.coupon_code)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
self.add_course_to_user_cart(self.testing_course.id)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# unit price should be updated for that course
|
||||
item = self.cart.orderitem_set.all().select_subclasses()[0]
|
||||
self.assertEquals(item.unit_cost, self.get_discount(self.cost))
|
||||
|
||||
item = self.cart.orderitem_set.all().select_subclasses()[1]
|
||||
self.assertEquals(item.unit_cost, self.get_discount(self.testing_cost))
|
||||
|
||||
def test_soft_delete_coupon(self): # pylint: disable=E1101
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
coupon = Coupon(code='TestCode', description='testing', course_id=self.course_key,
|
||||
percentage_discount=12, created_by=self.user, is_active=True)
|
||||
coupon.save()
|
||||
@@ -218,7 +256,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
def test_course_free_discount_for_valid_active_reg_code(self):
|
||||
|
||||
self.add_reg_code(self.course_key)
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -236,7 +274,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.debug')
|
||||
def test_non_existing_coupon_redemption_on_removing_item(self, debug_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
resp = self.client.post(reverse('shoppingcart.views.remove_item', args=[]),
|
||||
{'id': reg_item.id})
|
||||
debug_log.assert_called_with(
|
||||
@@ -248,8 +286,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_existing_coupon_redemption_on_removing_item(self, info_log):
|
||||
|
||||
self.add_coupon(self.course_key, True)
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -266,7 +304,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
def test_existing_reg_code_redemption_on_removing_item(self, info_log):
|
||||
|
||||
self.add_reg_code(self.course_key)
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -282,8 +320,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_coupon_discount_for_multiple_courses_in_cart(self, info_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, True)
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 2)
|
||||
|
||||
@@ -294,7 +332,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
items = self.cart.orderitem_set.all().select_subclasses()
|
||||
for item in items:
|
||||
if item.id == reg_item.id:
|
||||
self.assertEquals(item.unit_cost, self.get_discount())
|
||||
self.assertEquals(item.unit_cost, self.get_discount(self.cost))
|
||||
elif item.id == cert_item.id:
|
||||
self.assertEquals(item.list_price, None)
|
||||
|
||||
@@ -310,7 +348,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_reg_code_free_discount_with_multiple_courses_in_cart(self, info_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
self.add_reg_code(self.course_key)
|
||||
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 2)
|
||||
@@ -338,7 +376,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_delete_certificate_item(self, info_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 2)
|
||||
|
||||
@@ -354,11 +392,11 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_remove_coupon_redemption_on_clear_cart(self, info_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 2)
|
||||
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@@ -372,7 +410,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
@patch('shoppingcart.views.log.info')
|
||||
def test_remove_registration_code_redemption_on_clear_cart(self, info_log):
|
||||
|
||||
reg_item = self.add_course_to_user_cart()
|
||||
reg_item = self.add_course_to_user_cart(self.course_key)
|
||||
CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 2)
|
||||
|
||||
@@ -504,9 +542,9 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
self.assertEqual(resp2.status_code, 404)
|
||||
|
||||
def test_total_amount_of_purchased_course(self):
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 1)
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@@ -526,8 +564,8 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_show_receipt_success_with_valid_coupon_code(self):
|
||||
self.add_course_to_user_cart()
|
||||
self.add_coupon(self.course_key, True)
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
self.add_coupon(self.course_key, True, self.coupon_code)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -536,14 +574,14 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('FirstNameTesting123', resp.content)
|
||||
self.assertIn(str(self.get_discount()), resp.content)
|
||||
self.assertIn(str(self.get_discount(self.cost)), resp.content)
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_reg_code_and_course_registration_scenario(self):
|
||||
self.add_reg_code(self.course_key)
|
||||
|
||||
# One courses in user shopping cart
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
self.assertEquals(self.cart.orderitem_set.count(), 1)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
|
||||
@@ -585,7 +623,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_show_receipt_success_with_valid_reg_code(self):
|
||||
self.add_course_to_user_cart()
|
||||
self.add_course_to_user_cart(self.course_key)
|
||||
self.add_reg_code(self.course_key)
|
||||
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
|
||||
|
||||
@@ -15,7 +15,8 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from shoppingcart.reports import RefundReport, ItemizedPurchaseReport, UniversityRevenueShareReport, CertificateStatusReport
|
||||
from student.models import CourseEnrollment
|
||||
from .exceptions import ItemAlreadyInCartException, AlreadyEnrolledInCourseException, CourseDoesNotExistException, ReportTypeDoesNotExistException, \
|
||||
CouponAlreadyExistException, ItemDoesNotExistAgainstCouponException, RegCodeAlreadyExistException, ItemDoesNotExistAgainstRegCodeException
|
||||
RegCodeAlreadyExistException, ItemDoesNotExistAgainstRegCodeException,\
|
||||
MultipleCouponsNotAllowedException
|
||||
from .models import Order, PaidCourseRegistration, OrderItem, Coupon, CouponRedemption, CourseRegistrationCode, RegistrationCodeRedemption
|
||||
from .processors import process_postpay_callback, render_purchase_form_html
|
||||
import json
|
||||
@@ -154,9 +155,8 @@ def use_code(request):
|
||||
Valid Code can be either coupon or registration code.
|
||||
"""
|
||||
code = request.POST["code"]
|
||||
try:
|
||||
coupon = Coupon.objects.get(code=code, is_active=True)
|
||||
except Coupon.DoesNotExist:
|
||||
coupons = Coupon.objects.filter(code=code, is_active=True)
|
||||
if not coupons:
|
||||
# If not coupon code then we check that code against course registration code
|
||||
try:
|
||||
course_reg = CourseRegistrationCode.objects.get(code=code)
|
||||
@@ -165,7 +165,7 @@ def use_code(request):
|
||||
|
||||
return use_registration_code(course_reg, request.user)
|
||||
|
||||
return use_coupon_code(coupon, request.user)
|
||||
return use_coupon_code(coupons, request.user)
|
||||
|
||||
|
||||
def use_registration_code(course_reg, user):
|
||||
@@ -183,17 +183,23 @@ def use_registration_code(course_reg, user):
|
||||
return HttpResponse(json.dumps({'response': 'success'}), content_type="application/json")
|
||||
|
||||
|
||||
def use_coupon_code(coupon, user):
|
||||
def use_coupon_code(coupons, user):
|
||||
"""
|
||||
This method utilize course coupon code
|
||||
"""
|
||||
try:
|
||||
cart = Order.get_cart_for_user(user)
|
||||
CouponRedemption.add_coupon_redemption(coupon, cart)
|
||||
except CouponAlreadyExistException:
|
||||
return HttpResponseBadRequest(_("Coupon '{0}' already used.".format(coupon.code)))
|
||||
except ItemDoesNotExistAgainstCouponException:
|
||||
return HttpResponseNotFound(_("Coupon '{0}' is not valid for any course in the shopping cart.".format(coupon.code)))
|
||||
cart = Order.get_cart_for_user(user)
|
||||
cart_items = cart.orderitem_set.all().select_subclasses()
|
||||
is_redemption_applied = False
|
||||
for coupon in coupons:
|
||||
try:
|
||||
if CouponRedemption.add_coupon_redemption(coupon, cart, cart_items):
|
||||
is_redemption_applied = True
|
||||
except MultipleCouponsNotAllowedException:
|
||||
return HttpResponseBadRequest(_("Only one coupon redemption is allowed against an order"))
|
||||
|
||||
if not is_redemption_applied:
|
||||
log.warning("Course item does not exist for coupon '{0}'".format(coupons[0].code))
|
||||
return HttpResponseNotFound(_("Coupon '{0}' is not valid for any course in the shopping cart.".format(coupons[0].code)))
|
||||
|
||||
return HttpResponse(json.dumps({'response': 'success'}), content_type="application/json")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user