Commit c40aa66d by chrisndodge

Merge pull request #8081 from edx/muhhshoaib/MAYB-65-MIT-PE-double-coupon-use-reported

MAYN-65 fixed the bug, removed the redemption table entry when the item is expired from the user cart
parents 930ccd63 72bf9a5a
......@@ -181,13 +181,16 @@ class Order(models.Model):
return False
@classmethod
def remove_cart_item_from_order(cls, item):
def remove_cart_item_from_order(cls, item, user):
"""
Removes the item from the cart if the item.order.status == 'cart'.
Also removes any code redemption associated with the order_item
"""
if item.order.status == 'cart':
log.info("Item {0} removed from the user cart".format(item.id))
log.info("order item %s removed for user %s", str(item.id), user)
item.delete()
# remove any redemption entry associated with the item
CouponRedemption.remove_code_redemption_from_item(item, user)
@property
def total_cost(self):
......@@ -1235,7 +1238,31 @@ class CouponRedemption(models.Model):
coupon = models.ForeignKey(Coupon, db_index=True)
@classmethod
def delete_coupon_redemption(cls, user, cart):
def remove_code_redemption_from_item(cls, item, user):
"""
If an item removed from shopping cart then we will remove
the corresponding redemption info of coupon code
"""
order_item_course_id = getattr(item, 'course_id')
try:
# Try to remove redemption information of coupon code, If exist.
coupon_redemption = cls.objects.get(
user=user,
coupon__course_id=order_item_course_id if order_item_course_id else CourseKeyField.Empty,
order=item.order_id
)
coupon_redemption.delete()
log.info(
u'Coupon "%s" redemption entry removed for user "%s" for order item "%s"',
coupon_redemption.coupon.code,
user,
str(item.id),
)
except CouponRedemption.DoesNotExist:
log.debug(u'Code redemption does not exist for order item id=%s.', str(item.id))
@classmethod
def remove_coupon_redemption_from_cart(cls, user, cart):
"""
This method delete coupon redemption
"""
......
......@@ -35,8 +35,8 @@ from shoppingcart.views import _can_download_report, _get_date_from_str
from shoppingcart.models import (
Order, CertificateItem, PaidCourseRegistration, CourseRegCodeItem,
Coupon, CourseRegistrationCode, RegistrationCodeRedemption,
DonationConfiguration
)
DonationConfiguration,
CouponRedemption)
from student.tests.factories import UserFactory, AdminFactory, CourseModeFactory
from courseware.tests.factories import InstructorFactory
from student.models import CourseEnrollment
......@@ -674,11 +674,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
self.assertEqual(resp.status_code, 200)
self.assertEquals(self.cart.orderitem_set.count(), 1)
info_log.assert_called_with(
'order item %s removed for user %s',
str(cert_item.id),
self.user
)
info_log.assert_called_with("order item %s removed for user %s", str(cert_item.id), self.user)
@patch('shoppingcart.views.log.info')
def test_remove_coupon_redemption_on_clear_cart(self, info_log):
......@@ -1402,6 +1398,8 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
display_name='Testing Super Course',
metadata={"invitation_only": False}
)
self.percentage_discount = 20.0
self.coupon_code = 'asdsad'
self.course_mode = CourseMode(course_id=self.testing_course.id,
mode_slug="honor",
mode_display_name="honor cert",
......@@ -1412,6 +1410,14 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
self.tomorrow = self.now + timedelta(days=1)
self.nextday = self.tomorrow + timedelta(days=1)
def add_coupon(self, course_key, is_active, code):
"""
add dummy coupon into models
"""
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()
def login_user(self):
"""
Helper fn to login self.user
......@@ -1422,19 +1428,32 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
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)
expired_course_item = 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)
# now add the same coupon code to the second course(testing_course)
self.add_coupon(self.testing_course.id, True, self.coupon_code)
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.coupon_code})
self.assertEqual(resp.status_code, 200)
coupon_redemption = CouponRedemption.objects.filter(coupon__course_id=getattr(expired_course_item, 'course_id'),
order=expired_course_item.order_id)
self.assertEqual(coupon_redemption.count(), 1)
# 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
# coupon redemption entry should also be deleted when the item is expired.
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)
# now the redemption entry should be deleted from the table.
coupon_redemption = CouponRedemption.objects.filter(coupon__course_id=getattr(expired_course_item, 'course_id'),
order=expired_course_item.order_id)
self.assertEqual(coupon_redemption.count(), 0)
((template, context), _tmp) = render_mock.call_args
self.assertEqual(template, 'shoppingcart/shopping_cart.html')
self.assertEqual(context['order'], self.cart)
......
......@@ -174,7 +174,7 @@ def show_cart(request):
if is_any_course_expired:
for expired_item in expired_cart_items:
Order.remove_cart_item_from_order(expired_item)
Order.remove_cart_item_from_order(expired_item, request.user)
cart.update_order_type()
appended_expired_course_names = ", ".join(expired_cart_item_names)
......@@ -232,42 +232,12 @@ def remove_item(request):
else:
item = items[0]
if item.user == request.user:
order_item_course_id = getattr(item, 'course_id')
item.delete()
log.info(
u'order item %s removed for user %s',
item_id,
request.user,
)
remove_code_redemption(order_item_course_id, item_id, item, request.user)
Order.remove_cart_item_from_order(item, request.user)
item.order.update_order_type()
return HttpResponse('OK')
def remove_code_redemption(order_item_course_id, item_id, item, user):
"""
If an item removed from shopping cart then we will remove
the corresponding redemption info of coupon code
"""
try:
# Try to remove redemption information of coupon code, If exist.
coupon_redemption = CouponRedemption.objects.get(
user=user,
coupon__course_id=order_item_course_id if order_item_course_id else CourseKeyField.Empty,
order=item.order_id
)
coupon_redemption.delete()
log.info(
u'Coupon "%s" redemption entry removed for user "%s" for order item "%s"',
coupon_redemption.coupon.code,
user,
item_id,
)
except CouponRedemption.DoesNotExist:
log.debug(u'Code redemption does not exist for order item id=%s.', item_id)
@login_required
@enforce_shopping_cart_enabled
def reset_code_redemption(request):
......@@ -276,7 +246,7 @@ def reset_code_redemption(request):
"""
cart = Order.get_cart_for_user(request.user)
cart.reset_cart_items_prices()
CouponRedemption.delete_coupon_redemption(request.user, cart)
CouponRedemption.remove_coupon_redemption_from_cart(request.user, cart)
return HttpResponse('reset')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment