From 4cff92b0ad3a01c27c00137604fbf7699df67198 Mon Sep 17 00:00:00 2001 From: "hasnain.naveed" Date: Thu, 9 Apr 2020 18:12:24 +0500 Subject: [PATCH] ENT-2735 | Added the payment message on track selection for learners in subsidy offer. --- common/djangoapps/course_modes/helpers.py | 20 +++++++++++ .../course_modes/tests/test_views.py | 35 +++++++++++++++++++ common/djangoapps/course_modes/views.py | 10 ++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/common/djangoapps/course_modes/helpers.py b/common/djangoapps/course_modes/helpers.py index 42e33f6d77..6b41234bf9 100644 --- a/common/djangoapps/course_modes/helpers.py +++ b/common/djangoapps/course_modes/helpers.py @@ -4,8 +4,12 @@ import six from django.utils.translation import ugettext_lazy as _ +from requests.exceptions import ConnectionError, Timeout # pylint: disable=redefined-builtin +from slumber.exceptions import SlumberBaseException + from course_modes.models import CourseMode from student.helpers import VERIFY_STATUS_APPROVED, VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED +from openedx.core.djangoapps.commerce.utils import ecommerce_api_client DISPLAY_VERIFIED = "verified" DISPLAY_HONOR = "honor" @@ -83,3 +87,19 @@ def _enrollment_mode_display(enrollment_mode, verification_status, course_id): display_mode = enrollment_mode return display_mode + + +def get_course_final_price(user, sku, min_price): + """ + Return the course's discounted price for a user if user is entitled other None. + """ + price_details = {} + try: + price_details = ecommerce_api_client(user).baskets.calculate.get( + sku=[sku], + username=user.username, + ) + except (SlumberBaseException, ConnectionError, Timeout) as exc: # pylint: disable=unused-variable + pass + price = price_details.get('total_incl_tax', min_price) + return price if price != min_price else None diff --git a/common/djangoapps/course_modes/tests/test_views.py b/common/djangoapps/course_modes/tests/test_views.py index f3257a353b..8cb92484c1 100644 --- a/common/djangoapps/course_modes/tests/test_views.py +++ b/common/djangoapps/course_modes/tests/test_views.py @@ -198,6 +198,41 @@ class CourseModeViewTest(CatalogIntegrationMixin, UrlResetMixin, ModuleStoreTest else: self.assertNotContains(response, "Credit") + @httpretty.activate + @patch('course_modes.views.is_enterprise_learner') + @patch('course_modes.views.get_course_final_price') + @ddt.data( + (1.0, True), + (50.0, False), + (0.0, True), + (None, False), + ) + @ddt.unpack + def test_display_after_discounted_price( + self, + discounted_price, + is_enterprise_learner, + mock_get_course_final_price, + mock_is_enterprise_learner + ): + # Create the course modes + CourseModeFactory.create(mode_slug='audit', course_id=self.course.id) + verified_mode = CourseModeFactory.create(mode_slug='verified', course_id=self.course.id, sku='dummy') + CourseEnrollmentFactory( + is_active=True, + course_id=self.course.id, + user=self.user + ) + + mock_is_enterprise_learner.return_value = is_enterprise_learner + mock_get_course_final_price.return_value = discounted_price + url = reverse('course_modes_choose', args=[six.text_type(self.course.id)]) + response = self.client.get(url) + + price = discounted_price if is_enterprise_learner else verified_mode.min_price + # response will have after discounted price. + self.assertContains(response, price) + @httpretty.activate @ddt.data(True, False) def test_congrats_on_enrollment_message(self, create_enrollment): diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py index cf039e342d..2e76af77a1 100644 --- a/common/djangoapps/course_modes/views.py +++ b/common/djangoapps/course_modes/views.py @@ -26,6 +26,7 @@ from opaque_keys.edx.keys import CourseKey from six import text_type from course_modes.models import CourseMode +from common.djangoapps.course_modes.helpers import get_course_final_price from edxmako.shortcuts import render_to_response from lms.djangoapps.commerce.utils import EcommerceService from lms.djangoapps.experiments.utils import get_experiment_user_metadata_context @@ -34,7 +35,7 @@ from openedx.core.djangoapps.embargo import api as embargo_api from openedx.core.djangoapps.enrollments.permissions import ENROLL_IN_COURSE from openedx.features.content_type_gating.models import ContentTypeGatingConfig from openedx.features.course_duration_limits.models import CourseDurationLimitConfig -from openedx.features.discounts.applicability import discount_percentage +from openedx.features.enterprise_support.utils import is_enterprise_learner from student.models import CourseEnrollment from util.db import outer_atomic from xmodule.modulestore.django import modulestore @@ -202,13 +203,18 @@ class ChooseModeView(View): for x in verified_mode.suggested_prices.split(",") if x.strip() ] + price_after_discount = None price_before_discount = verified_mode.min_price + if is_enterprise_learner(request.user) and verified_mode.sku: + price_after_discount = get_course_final_price(request.user, verified_mode.sku, price_before_discount) context["currency"] = verified_mode.currency.upper() context["currency_symbol"] = get_currency_symbol(verified_mode.currency.upper()) - context["min_price"] = price_before_discount + context["min_price"] = price_after_discount if price_after_discount is not None else price_before_discount context["verified_name"] = verified_mode.name context["verified_description"] = verified_mode.description + if price_after_discount is not None: + context["price_before_discount"] = price_before_discount if verified_mode.sku: context["use_ecommerce_payment_flow"] = ecommerce_service.is_enabled(request.user)