check course end date and verified mode for first purchase offer

This commit is contained in:
Matthew Piatetsky
2019-05-16 14:21:28 -04:00
parent 2d0662b49a
commit 93300a2e0e
4 changed files with 47 additions and 5 deletions

View File

@@ -196,7 +196,7 @@ def get_first_purchase_offer_banner_fragment(user, course):
if (FIRST_PURCHASE_OFFER_BANNER_DISPLAY.is_enabled() and if (FIRST_PURCHASE_OFFER_BANNER_DISPLAY.is_enabled() and
user and user and
course and course and
can_receive_discount(user=user, course_key_string=unicode(course.id))): can_receive_discount(user=user, course=course)):
# Translator: xgettext:no-python-format # Translator: xgettext:no-python-format
offer_message = _(u'{banner_open}{percentage}% off your first upgrade.{span_close}' offer_message = _(u'{banner_open}{percentage}% off your first upgrade.{span_close}'
u' Discount automatically applied.{div_close}') u' Discount automatically applied.{div_close}')

View File

@@ -2,7 +2,13 @@
""" """
Contains code related to computing discount percentage Contains code related to computing discount percentage
and discount applicability. and discount applicability.
WARNING:
Keep in mind that the code in this file only applies to discounts controlled in the lms like the first purchase offer,
not other discounts like coupons or enterprise/program offers configured in ecommerce.
""" """
from course_modes.models import CourseMode
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
# .. feature_toggle_name: discounts.enable_discounting # .. feature_toggle_name: discounts.enable_discounting
@@ -23,7 +29,7 @@ DISCOUNT_APPLICABILITY_FLAG = WaffleFlag(
) )
def can_receive_discount(user, course_key_string): # pylint: disable=unused-argument def can_receive_discount(user, course): # pylint: disable=unused-argument
""" """
Check all the business logic about whether this combination of user and course Check all the business logic about whether this combination of user and course
can receive a discount. can receive a discount.
@@ -34,6 +40,16 @@ def can_receive_discount(user, course_key_string): # pylint: disable=unused-arg
# TODO: Add additional conditions to return False here # TODO: Add additional conditions to return False here
# Course end date needs to be in the future
if course.has_ended():
return False
# Course needs to have a non-expired verified mode
modes_dict = CourseMode.modes_for_course_dict(course=course, include_expired=False)
verified_mode = modes_dict.get('verified', None)
if not verified_mode:
return False
return True return True

View File

@@ -1,11 +1,16 @@
"""Tests of openedx.features.discounts.applicability""" """Tests of openedx.features.discounts.applicability"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import timedelta
from django.utils.timezone import now
from course_modes.tests.factories import CourseModeFactory
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from ..applicability import can_receive_discount from ..applicability import can_receive_discount, DISCOUNT_APPLICABILITY_FLAG
class TestApplicability(ModuleStoreTestCase): class TestApplicability(ModuleStoreTestCase):
@@ -18,8 +23,25 @@ class TestApplicability(ModuleStoreTestCase):
super(TestApplicability, self).setUp() super(TestApplicability, self).setUp()
self.user = UserFactory.create() self.user = UserFactory.create()
self.course = CourseFactory.create(run='test', display_name='test') self.course = CourseFactory.create(run='test', display_name='test')
CourseModeFactory.create(course_id=self.course.id, mode_slug='verified')
def test_can_receive_discount(self): def test_can_receive_discount(self):
# Right now, no one should be able to receive the discount # Right now, no one should be able to receive the discount
applicability = can_receive_discount(user=self.user, course_key_string=self.course.id) applicability = can_receive_discount(user=self.user, course=self.course)
self.assertEqual(applicability, False)
@override_waffle_flag(DISCOUNT_APPLICABILITY_FLAG, active=True)
def test_can_receive_discount_course_requirements(self):
"""
Ensure first purchase offer banner only displays for courses with a non-expired verified mode
"""
applicability = can_receive_discount(user=self.user, course=self.course)
self.assertEqual(applicability, True)
no_verified_mode_course = CourseFactory(end=now() + timedelta(days=30))
applicability = can_receive_discount(user=self.user, course=no_verified_mode_course)
self.assertEqual(applicability, False)
course_that_has_ended = CourseFactory(end=now() - timedelta(days=30))
applicability = can_receive_discount(user=self.user, course=course_that_has_ended)
self.assertEqual(applicability, False) self.assertEqual(applicability, False)

View File

@@ -7,6 +7,8 @@ The Discount API Views should return information about discounts that apply to t
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
@@ -65,7 +67,9 @@ class CourseUserDiscount(DeveloperErrorViewMixin, APIView):
""" """
Return the discount percent, if the user has appropriate permissions. Return the discount percent, if the user has appropriate permissions.
""" """
discount_applicable = can_receive_discount(user=request.user, course_key_string=course_key_string) course_key = CourseKey.from_string(course_key_string)
course = CourseOverview.get_from_id(course_key)
discount_applicable = can_receive_discount(user=request.user, course=course)
discount_percent = discount_percentage() discount_percent = discount_percentage()
payload = {'discount_applicable': discount_applicable, 'discount_percent': discount_percent} payload = {'discount_applicable': discount_applicable, 'discount_percent': discount_percent}
return Response({ return Response({