Merge pull request #22156 from cpennington/expose-course-duration
Expose user course duration in the user metadata
This commit is contained in:
@@ -21,7 +21,7 @@ from openedx.core.djangoapps.catalog.utils import get_programs
|
||||
from openedx.core.djangoapps.django_comment_common.models import Role
|
||||
from openedx.core.djangoapps.schedules.models import Schedule
|
||||
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
|
||||
from openedx.features.course_duration_limits.access import get_user_course_expiration_date
|
||||
from openedx.features.course_duration_limits.access import get_user_course_expiration_date, get_user_course_duration
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from student.models import CourseEnrollment
|
||||
from xmodule.partitions.partitions_service import get_all_partitions_for_course, get_user_partition_groups
|
||||
@@ -324,6 +324,8 @@ def get_base_experiment_metadata_context(course, user, enrollment, user_enrollme
|
||||
user, enrollment, course
|
||||
)
|
||||
|
||||
deadline, duration = get_audit_access_expiration(user, course)
|
||||
|
||||
return {
|
||||
'upgrade_link': upgrade_link,
|
||||
'upgrade_price': six.text_type(get_cosmetic_verified_display_price(course)),
|
||||
@@ -333,7 +335,8 @@ def get_base_experiment_metadata_context(course, user, enrollment, user_enrollme
|
||||
'pacing_type': 'self_paced' if course.self_paced else 'instructor_paced',
|
||||
'dynamic_upgrade_deadline': dynamic_upgrade_deadline,
|
||||
'course_upgrade_deadline': course_upgrade_deadline,
|
||||
'audit_access_deadline': get_audit_access_expiration(user, course),
|
||||
'audit_access_deadline': deadline,
|
||||
'course_duration': duration,
|
||||
'course_key': course.id,
|
||||
'course_start': course.start,
|
||||
'course_end': course.end,
|
||||
@@ -345,12 +348,12 @@ def get_base_experiment_metadata_context(course, user, enrollment, user_enrollme
|
||||
|
||||
def get_audit_access_expiration(user, course):
|
||||
"""
|
||||
Return the expiration date for the user's audit access to this course.
|
||||
Return the expiration date and course duration for the user's audit access to this course.
|
||||
"""
|
||||
if not CourseDurationLimitConfig.enabled_for_enrollment(user=user, course_key=course.id):
|
||||
return None
|
||||
return None, None
|
||||
|
||||
return get_user_course_expiration_date(user, course)
|
||||
return get_user_course_expiration_date(user, course), get_user_course_duration(user, course)
|
||||
|
||||
|
||||
# TODO: clean up as part of REVEM-199 (START)
|
||||
|
||||
@@ -16,6 +16,7 @@ user_metadata = {
|
||||
'upgrade_link',
|
||||
'upgrade_price',
|
||||
'audit_access_deadline',
|
||||
'course_duration',
|
||||
'pacing_type',
|
||||
'has_staff_access',
|
||||
'forum_roles',
|
||||
@@ -42,11 +43,19 @@ for datekey in (
|
||||
'course_end',
|
||||
'dynamic_upgrade_deadline',
|
||||
'course_upgrade_deadline',
|
||||
'audit_access_deadline',
|
||||
):
|
||||
user_metadata[datekey] = (
|
||||
context.get(datekey).isoformat() if context.get(datekey) else None
|
||||
)
|
||||
|
||||
for timedeltakey in (
|
||||
'course_duration',
|
||||
):
|
||||
user_metadata[timedeltakey] = (
|
||||
context.get(timedeltakey).total_seconds() if context.get(timedeltake) else None
|
||||
)
|
||||
|
||||
course_key = context.get('course_key')
|
||||
if course and not course_key:
|
||||
course_key = course.id
|
||||
|
||||
@@ -54,6 +54,39 @@ class AuditExpiredError(AccessError):
|
||||
additional_context_user_message)
|
||||
|
||||
|
||||
def get_user_course_duration(user, course):
|
||||
"""
|
||||
Return a timedelta measuring the duration of the course for a particular user.
|
||||
|
||||
Business Logic:
|
||||
- Course access duration is bounded by the min and max duration.
|
||||
- If course fields are missing, default course access duration to MIN_DURATION.
|
||||
"""
|
||||
|
||||
access_duration = MIN_DURATION
|
||||
|
||||
verified_mode = CourseMode.verified_mode_for_course(course=course, include_expired=True)
|
||||
|
||||
if not verified_mode:
|
||||
return None
|
||||
|
||||
enrollment = CourseEnrollment.get_enrollment(user, course.id)
|
||||
if enrollment is None or enrollment.mode != CourseMode.AUDIT:
|
||||
return None
|
||||
|
||||
# The user course expiration date is the content availability date
|
||||
# plus the weeks_to_complete field from course-discovery.
|
||||
discovery_course_details = get_course_run_details(course.id, ['weeks_to_complete'])
|
||||
expected_weeks = discovery_course_details.get('weeks_to_complete')
|
||||
if expected_weeks:
|
||||
access_duration = timedelta(weeks=expected_weeks)
|
||||
|
||||
# Course access duration is bounded by the min and max duration.
|
||||
access_duration = max(MIN_DURATION, min(MAX_DURATION, access_duration))
|
||||
|
||||
return access_duration
|
||||
|
||||
|
||||
def get_user_course_expiration_date(user, course):
|
||||
"""
|
||||
Return expiration date for given user course pair.
|
||||
@@ -63,11 +96,8 @@ def get_user_course_expiration_date(user, course):
|
||||
- Course access duration is bounded by the min and max duration.
|
||||
- If course fields are missing, default course access duration to MIN_DURATION.
|
||||
"""
|
||||
access_duration = MIN_DURATION
|
||||
|
||||
verified_mode = CourseMode.verified_mode_for_course(course=course, include_expired=True)
|
||||
|
||||
if not verified_mode:
|
||||
access_duration = get_user_course_duration(user, course)
|
||||
if access_duration is None:
|
||||
return None
|
||||
|
||||
enrollment = CourseEnrollment.get_enrollment(user, course.id)
|
||||
@@ -90,16 +120,6 @@ def get_user_course_expiration_date(user, course):
|
||||
except CourseEnrollment.schedule.RelatedObjectDoesNotExist:
|
||||
content_availability_date = max(enrollment.created, course.start)
|
||||
|
||||
# The user course expiration date is the content availability date
|
||||
# plus the weeks_to_complete field from course-discovery.
|
||||
discovery_course_details = get_course_run_details(course.id, ['weeks_to_complete'])
|
||||
expected_weeks = discovery_course_details.get('weeks_to_complete')
|
||||
if expected_weeks:
|
||||
access_duration = timedelta(weeks=expected_weeks)
|
||||
|
||||
# Course access duration is bounded by the min and max duration.
|
||||
access_duration = max(MIN_DURATION, min(MAX_DURATION, access_duration))
|
||||
|
||||
return content_availability_date + access_duration
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user