Skip to content

Commit

Permalink
temp: disable price update for published courses (#4520)
Browse files Browse the repository at this point in the history
  • Loading branch information
AfaqShuaib09 authored Dec 20, 2024
1 parent 08b743b commit de6f25b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 25 deletions.
53 changes: 31 additions & 22 deletions course_discovery/apps/api/v1/views/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
Collaborator, Course, CourseEditor, CourseEntitlement, CourseRun, CourseType, CourseUrlSlug, Organization, Program,
Seat, Source, Video
)
from course_discovery.apps.course_metadata.toggles import IS_DISABLE_PRICE_UPDATES_FOR_PUBLISHED_RUNS
from course_discovery.apps.course_metadata.utils import (
create_missing_entitlement, ensure_draft_world, validate_course_number, validate_slug_format
)
Expand Down Expand Up @@ -338,28 +339,36 @@ def update_course(self, data, partial=False): # pylint: disable=too-many-statem
self.log_request_subjects_and_prices(data, course)

# First, update course entitlements
if data.get('type') or data.get('prices'):
entitlements = []
prices = data.get('prices', {})
course_type = CourseType.objects.get(uuid=data.get('type')) if data.get('type') else course.type
entitlement_types = course_type.entitlement_types.all()
for entitlement_type in entitlement_types:
price = prices.get(entitlement_type.slug)
if price is None:
continue
entitlement, did_change = self.update_entitlement(course, entitlement_type, price, partial=partial)
entitlements.append(entitlement)
changed = changed or did_change
# Deleting entitlements here since they would be orphaned otherwise.
# One example of how this situation can happen is if a course team is switching between
# "Verified and Audit" and "Audit Only" before actually publishing their course run.
course.entitlements.exclude(mode__in=entitlement_types).delete()
course.entitlements.set(entitlements)

# If entitlement has changed, get updated course object from DB that has new value for
# data modified timestamp.
if changed:
course.refresh_from_db()
is_price_update_disabled = IS_DISABLE_PRICE_UPDATES_FOR_PUBLISHED_RUNS.is_enabled()
has_no_published_runs = not any(
course_run.status == CourseRunStatus.Published for course_run in course.active_course_runs
)
if (
course.is_external_course or not is_price_update_disabled or
(is_price_update_disabled and has_no_published_runs)
):
if data.get('type') or data.get('prices'):
entitlements = []
prices = data.get('prices', {})
course_type = CourseType.objects.get(uuid=data.get('type')) if data.get('type') else course.type
entitlement_types = course_type.entitlement_types.all()
for entitlement_type in entitlement_types:
price = prices.get(entitlement_type.slug)
if price is None:
continue
entitlement, did_change = self.update_entitlement(course, entitlement_type, price, partial=partial)
entitlements.append(entitlement)
changed = changed or did_change
# Deleting entitlements here since they would be orphaned otherwise.
# One example of how this situation can happen is if a course team is switching between
# "Verified and Audit" and "Audit Only" before actually publishing their course run.
course.entitlements.exclude(mode__in=entitlement_types).delete()
course.entitlements.set(entitlements)

# If entitlement has changed, get updated course object from DB that has new value for
# data modified timestamp.
if changed:
course.refresh_from_db()

# Save video if a new video source is provided, also allow removing the video from course
if video_data:
Expand Down
12 changes: 9 additions & 3 deletions course_discovery/apps/course_metadata/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
)
from course_discovery.apps.course_metadata.query import CourseQuerySet, CourseRunQuerySet, ProgramQuerySet
from course_discovery.apps.course_metadata.toggles import (
IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED,
IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED
IS_DISABLE_PRICE_UPDATES_FOR_PUBLISHED_RUNS, IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED,
IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED, IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED
)
from course_discovery.apps.course_metadata.utils import (
UploadToFieldNamePath, clean_query, clear_slug_request_cache_for_course, custom_render_variations,
Expand Down Expand Up @@ -2681,11 +2681,17 @@ def get_seat_upgrade_deadline(self, seat_type):
return deadline

def update_or_create_seat_helper(self, seat_type, prices, upgrade_deadline_override):
is_price_update_disabled = IS_DISABLE_PRICE_UPDATES_FOR_PUBLISHED_RUNS.is_enabled()
defaults = {
'upgrade_deadline': self.get_seat_upgrade_deadline(seat_type),
}
if seat_type.slug in prices:
defaults['price'] = prices[seat_type.slug]
if (
self.course.is_external_course or not is_price_update_disabled or (
self.status != CourseRunStatus.Published and is_price_update_disabled
)
):
defaults['price'] = prices[seat_type.slug]

if upgrade_deadline_override and seat_type.slug == Seat.VERIFIED:
defaults['upgrade_deadline_override'] = upgrade_deadline_override
Expand Down
12 changes: 12 additions & 0 deletions course_discovery/apps/course_metadata/toggles.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,15 @@
IS_COURSE_RUN_VARIANT_ID_ECOMMERCE_CONSUMABLE = WaffleSwitch(
'course_metadata.is_course_run_variant_id_ecommerce_consumable', __name__
)
# .. toggle_name: course_metadata.is_disable_price_updates_for_published_runs
# .. toggle_implementation: WaffleSwitch
# .. toggle_default: False
# .. toggle_description: Temporary toggle to disable price updates for published course runs.
# .. toggle_use_cases: open_edx
# .. toggle_type: temporary
# .. toggle_creation_date: 2024-12-20
# .. toggle_target_removal_date: 2025-01-05
# .. toggle_tickets: PROD-4264
IS_DISABLE_PRICE_UPDATES_FOR_PUBLISHED_RUNS = WaffleSwitch(
'course_metadata.is_disable_price_updates_for_published_runs', __name__
)

0 comments on commit de6f25b

Please sign in to comment.