From 6a63cfcaa40420ba41872faddddcf31a9fe83c60 Mon Sep 17 00:00:00 2001 From: Mohammad Ahtasham ul Hassan <60315450+aht007@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:15:51 +0500 Subject: [PATCH] feat: add override option to upgrade CTA utils and add course_run_key identifier (#35441) * feat: add override option to upgrade CTAs and send course_run_key identifier --- common/djangoapps/course_modes/views.py | 8 ++++++-- lms/djangoapps/commerce/utils.py | 9 +++++++-- lms/djangoapps/courseware/views/views.py | 8 ++++++-- lms/djangoapps/verify_student/views.py | 3 ++- openedx/core/djangoapps/programs/utils.py | 4 +++- openedx/features/content_type_gating/partitions.py | 6 +++--- openedx/features/discounts/utils.py | 2 ++ 7 files changed, 29 insertions(+), 11 deletions(-) diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py index 269961424d04..821c59dc0524 100644 --- a/common/djangoapps/course_modes/views.py +++ b/common/djangoapps/course_modes/views.py @@ -126,9 +126,13 @@ def get(self, request, course_id, error=None): # lint-amnesty, pylint: disable= if ecommerce_service.is_enabled(request.user): professional_mode = modes.get(CourseMode.NO_ID_PROFESSIONAL_MODE) or modes.get(CourseMode.PROFESSIONAL) if purchase_workflow == "single" and professional_mode.sku: - redirect_url = ecommerce_service.get_checkout_page_url(professional_mode.sku) + redirect_url = ecommerce_service.get_checkout_page_url( + professional_mode.sku, course_run_keys=[course_id] + ) if purchase_workflow == "bulk" and professional_mode.bulk_sku: - redirect_url = ecommerce_service.get_checkout_page_url(professional_mode.bulk_sku) + redirect_url = ecommerce_service.get_checkout_page_url( + professional_mode.bulk_sku, course_run_keys=[course_id] + ) return redirect(redirect_url) course = modulestore().get_course(course_key) diff --git a/lms/djangoapps/commerce/utils.py b/lms/djangoapps/commerce/utils.py index a37cd2ab36b2..82ed8c483024 100644 --- a/lms/djangoapps/commerce/utils.py +++ b/lms/djangoapps/commerce/utils.py @@ -27,6 +27,7 @@ should_redirect_to_commerce_coordinator_checkout, should_redirect_to_commerce_coordinator_refunds, ) +from edx_django_utils.plugins import pluggable_override log = logging.getLogger(__name__) @@ -56,6 +57,7 @@ def ecommerce_url_root(self): """ Retrieve Ecommerce service public url root. """ return configuration_helpers.get_value('ECOMMERCE_PUBLIC_URL_ROOT', settings.ECOMMERCE_PUBLIC_URL_ROOT) + @pluggable_override('OVERRIDE_GET_ABSOLUTE_ECOMMERCE_URL') def get_absolute_ecommerce_url(self, ecommerce_page_url): """ Return the absolute URL to the ecommerce page. @@ -110,7 +112,6 @@ def payment_page_url(self): def get_add_to_basket_url(self): """ Return the URL for the payment page based on the waffle switch. - Example: http://localhost/enabled_service_api_path """ @@ -118,12 +119,14 @@ def get_add_to_basket_url(self): return urljoin(settings.COMMERCE_COORDINATOR_URL_ROOT, settings.COORDINATOR_CHECKOUT_REDIRECT_PATH) return self.payment_page_url() + @pluggable_override('OVERRIDE_GET_CHECKOUT_PAGE_URL') def get_checkout_page_url(self, *skus, **kwargs): """ Construct the URL to the ecommerce checkout page and include products. Args: skus (list): List of SKUs associated with products to be added to basket program_uuid (string): The UUID of the program, if applicable + course_run_keys (list): The course run keys of the products to be added to basket. Returns: Absolute path to the ecommerce checkout page showing basket that contains specified products. @@ -153,10 +156,12 @@ def upgrade_url(self, user, course_key): """ Returns the URL for the user to upgrade, or None if not applicable. """ + course_run_key = str(course_key) + verified_mode = CourseMode.verified_mode_for_course(course_key) if verified_mode: if self.is_enabled(user): - return self.get_checkout_page_url(verified_mode.sku) + return self.get_checkout_page_url(verified_mode.sku, course_run_keys=[course_run_key]) else: return reverse('dashboard') return None diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 95af0cf75f06..79a52db8a0b6 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -825,9 +825,13 @@ def course_about(request, course_id): # pylint: disable=too-many-statements single_paid_mode = modes.get(CourseMode.PROFESSIONAL) if single_paid_mode and single_paid_mode.sku: - ecommerce_checkout_link = ecomm_service.get_checkout_page_url(single_paid_mode.sku) + ecommerce_checkout_link = ecomm_service.get_checkout_page_url( + single_paid_mode.sku, course_run_keys=[course_id] + ) if single_paid_mode and single_paid_mode.bulk_sku: - ecommerce_bulk_checkout_link = ecomm_service.get_checkout_page_url(single_paid_mode.bulk_sku) + ecommerce_bulk_checkout_link = ecomm_service.get_checkout_page_url( + single_paid_mode.bulk_sku, course_run_keys=[course_id] + ) registration_price, course_price = get_course_prices(course) # lint-amnesty, pylint: disable=unused-variable diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py index 8c1912d9c2f8..1b6a47bee879 100644 --- a/lms/djangoapps/verify_student/views.py +++ b/lms/djangoapps/verify_student/views.py @@ -503,7 +503,8 @@ def _redirect_if_necessary( if ecommerce_service.is_enabled(user): url = ecommerce_service.get_checkout_page_url( sku, - catalog=self.request.GET.get('catalog') + catalog=self.request.GET.get('catalog'), + course_run_keys=[str(course_key)] ) # Redirect if necessary, otherwise implicitly return None diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py index b842b8b363b6..95044a6faeff 100644 --- a/openedx/core/djangoapps/programs/utils.py +++ b/openedx/core/djangoapps/programs/utils.py @@ -631,7 +631,9 @@ def _attach_course_run_upgrade_url(self, run_mode): ecommerce = EcommerceService() sku = getattr(required_mode, "sku", None) if ecommerce.is_enabled(self.user) and sku: - run_mode["upgrade_url"] = ecommerce.get_checkout_page_url(required_mode.sku) + run_mode["upgrade_url"] = ecommerce.get_checkout_page_url( + required_mode.sku, course_run_keys=[self.course_run_key] + ) else: run_mode["upgrade_url"] = None else: diff --git a/openedx/features/content_type_gating/partitions.py b/openedx/features/content_type_gating/partitions.py index 5f48ab609133..61851ec43bbd 100644 --- a/openedx/features/content_type_gating/partitions.py +++ b/openedx/features/content_type_gating/partitions.py @@ -91,7 +91,7 @@ def access_denied_fragment(self, block, user, user_group, allowed_groups): if expiration_datetime and expiration_datetime < datetime.datetime.now(pytz.UTC): ecommerce_checkout_link = None else: - ecommerce_checkout_link = self._get_checkout_link(user, verified_mode.sku) + ecommerce_checkout_link = self._get_checkout_link(user, verified_mode.sku, str(course_key)) request = crum.get_current_request() @@ -118,11 +118,11 @@ def access_denied_message(self, block_key, user, user_group, allowed_groups): else: return _("Graded assessments are available to Verified Track learners. Upgrade to Unlock.") - def _get_checkout_link(self, user, sku): + def _get_checkout_link(self, user, sku, course_run_key): ecomm_service = EcommerceService() ecommerce_checkout = ecomm_service.is_enabled(user) if ecommerce_checkout and sku: - return ecomm_service.get_checkout_page_url(sku) or '' + return ecomm_service.get_checkout_page_url(sku, course_run_keys=[course_run_key]) or '' def _get_course_key_from_course_block(self, block): """ diff --git a/openedx/features/discounts/utils.py b/openedx/features/discounts/utils.py index e97524d4381a..92490f19bcb3 100644 --- a/openedx/features/discounts/utils.py +++ b/openedx/features/discounts/utils.py @@ -8,6 +8,7 @@ from django.conf import settings from django.utils.translation import get_language from django.utils.translation import gettext as _ +from edx_django_utils.plugins import pluggable_override from common.djangoapps.course_modes.models import format_course_price, get_course_prices from lms.djangoapps.experiments.models import ExperimentData @@ -73,6 +74,7 @@ def _get_discount_prices(user, course, assume_discount=False): return format_course_price(base_price), None, None +@pluggable_override("OVERRIDE_GENERATE_OFFER_DATA") def generate_offer_data(user, course): """ Create a dictionary of information about the current discount offer.