diff --git a/lms/djangoapps/course_home_api/dates/v1/views.py b/lms/djangoapps/course_home_api/dates/v1/views.py index 2dbea61418..efd184466a 100644 --- a/lms/djangoapps/course_home_api/dates/v1/views.py +++ b/lms/djangoapps/course_home_api/dates/v1/views.py @@ -2,7 +2,6 @@ Dates Tab Views """ - from rest_framework import status from rest_framework.generics import RetrieveAPIView from rest_framework.permissions import IsAuthenticated @@ -85,6 +84,7 @@ class DatesTabView(RetrieveAPIView): user_timezone = user_timezone_locale['user_timezone'] data = { + 'has_ended': course.has_ended(), 'course_date_blocks': [block for block in blocks if not isinstance(block, TodaysDate)], 'missed_deadlines': missed_deadlines, 'missed_gated_content': missed_gated_content, diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py index a03f248ef5..e1bd3864c6 100644 --- a/lms/djangoapps/courseware/date_summary.py +++ b/lms/djangoapps/courseware/date_summary.py @@ -327,7 +327,7 @@ class CourseEndDate(DateSummary): weeks_to_complete = get_course_run_details(self.course.id, ['weeks_to_complete']).get('weeks_to_complete') if weeks_to_complete: course_duration = datetime.timedelta(weeks=weeks_to_complete) - if self.course.end < (self.current_time + course_duration): + if self.course.end and self.course.end < (self.current_time + course_duration): return self.course.end return None diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 3fba89aeee..45c7462cd3 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -1081,7 +1081,8 @@ def dates(request, course_id): 'missed_gated_content': missed_gated_content, 'reset_deadlines_url': reverse(RESET_COURSE_DEADLINES_NAME), 'reset_deadlines_redirect_url_base': COURSE_DATES_NAME, - 'reset_deadlines_redirect_url_id_dict': {'course_id': str(course.id)} + 'reset_deadlines_redirect_url_id_dict': {'course_id': str(course.id)}, + 'has_ended': course.has_ended(), } return render_to_response('courseware/dates.html', context) @@ -1680,6 +1681,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True): 'xqa_server': settings.FEATURES.get('XQA_SERVER', 'http://your_xqa_server.com'), 'missed_deadlines': missed_deadlines, 'missed_gated_content': missed_gated_content, + 'has_ended': course.has_ended(), 'web_app_course_url': reverse(COURSE_HOME_VIEW_NAME, args=[course.id]), 'on_courseware_page': True, 'verified_upgrade_link': verified_upgrade_deadline_link(request.user, course=course), diff --git a/lms/templates/dates_banner.html b/lms/templates/dates_banner.html index b6f127c5a2..3b140cf53c 100644 --- a/lms/templates/dates_banner.html +++ b/lms/templates/dates_banner.html @@ -8,14 +8,6 @@ from lms.djangoapps.courseware.date_summary import CourseAssignmentDate from course_modes.models import CourseMode %> -% if on_dates_tab and not missed_deadlines and getattr(course, 'self_paced', False): -
-
- ${_("We've built a suggested schedule to help you stay on track.")} - ${_("But don't worry—it's flexible so you can learn at your own pace. If you happen to fall behind on our suggested dates, you'll be able to adjust them to keep yourself on track.")} -
-
-% endif <% additional_styling_class = 'on-mobile' if is_mobile_app else 'has-button' %> @@ -93,13 +85,25 @@ additional_styling_class = 'on-mobile' if is_mobile_app else 'has-button' % endif -% if on_dates_tab and content_type_gating_enabled and not missed_deadlines: - ${upgrade_to_complete_graded_banner()} -% elif missed_deadlines: - % if missed_gated_content: - ${upgrade_to_reset_banner()} - % else: - ${reset_dates_banner()} + +% if not has_ended: + % if on_dates_tab and not missed_deadlines: + %if getattr(course, 'self_paced', False): +
+
+ ${_("We've built a suggested schedule to help you stay on track.")} + ${_("But don't worry—it's flexible so you can learn at your own pace. If you happen to fall behind on our suggested dates, you'll be able to adjust them to keep yourself on track.")} +
+
+ % endif + % if content_type_gating_enabled: + ${upgrade_to_complete_graded_banner()} + % endif + % elif missed_deadlines: + % if missed_gated_content: + ${upgrade_to_reset_banner()} + % else: + ${reset_dates_banner()} + % endif % endif % endif - diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index cfaaba190f..61acf1dbd9 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -794,7 +794,7 @@ class TestProgramDataExtender(ModuleStoreTestCase): 'certificate_url': None, 'course_url': reverse('course_root', args=[self.course.id]), 'enrollment_open_date': strftime_localized(DEFAULT_ENROLLMENT_START_DATE, 'SHORT_DATE'), - 'is_course_ended': self.course.end < datetime.datetime.now(utc), + 'is_course_ended': self.course.has_ended(), 'is_enrolled': False, 'is_enrollment_open': True, 'upgrade_url': None, diff --git a/openedx/features/course_experience/views/course_outline.py b/openedx/features/course_experience/views/course_outline.py index f2e8e5a77e..1b4f7b1f8c 100644 --- a/openedx/features/course_experience/views/course_outline.py +++ b/openedx/features/course_experience/views/course_outline.py @@ -67,15 +67,6 @@ class CourseOutlineFragmentView(EdxFragmentView): if not course_block_tree: return None - context = { - 'csrf': csrf(request)['csrf_token'], - 'course': course_overview, - 'due_date_display_format': course.due_date_display_format, - 'blocks': course_block_tree, - 'enable_links': user_is_enrolled or course.course_visibility == COURSE_VISIBILITY_PUBLIC, - 'course_key': course_key, - } - resume_block = get_resume_block(course_block_tree) if user_is_enrolled else None if not resume_block: @@ -86,27 +77,32 @@ class CourseOutlineFragmentView(EdxFragmentView): missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request.user) - context['gated_content'] = gated_content - context['xblock_display_names'] = xblock_display_names - - page_context = kwargs.get('page_context', None) - if page_context: - context['self_paced'] = page_context.get('pacing_type', 'instructor_paced') == 'self_paced' - - # We're using this flag to prevent old self-paced dates from leaking out on courses not - # managed by edx-when. - context['in_edx_when'] = edx_when_api.is_enabled_for_course(course_key) - reset_deadlines_url = reverse(RESET_COURSE_DEADLINES_NAME) reset_deadlines_redirect_url_base = COURSE_HOME_VIEW_NAME - context['reset_deadlines_url'] = reset_deadlines_url - context['reset_deadlines_redirect_url_base'] = reset_deadlines_redirect_url_base - context['reset_deadlines_redirect_url_id_dict'] = {'course_id': str(course.id)} - context['verified_upgrade_link'] = verified_upgrade_deadline_link(request.user, course=course) - context['on_course_outline_page'] = True - context['missed_deadlines'] = missed_deadlines - context['missed_gated_content'] = missed_gated_content + context = { + 'csrf': csrf(request)['csrf_token'], + 'course': course_overview, + 'due_date_display_format': course.due_date_display_format, + 'blocks': course_block_tree, + 'enable_links': user_is_enrolled or course.course_visibility == COURSE_VISIBILITY_PUBLIC, + 'course_key': course_key, + 'gated_content': gated_content, + 'xblock_display_names': xblock_display_names, + 'self_paced': course.self_paced, + + # We're using this flag to prevent old self-paced dates from leaking out on courses not + # managed by edx-when. + 'in_edx_when': edx_when_api.is_enabled_for_course(course_key), + 'reset_deadlines_url': reset_deadlines_url, + 'reset_deadlines_redirect_url_base': reset_deadlines_redirect_url_base, + 'reset_deadlines_redirect_url_id_dict': {'course_id': str(course.id)}, + 'verified_upgrade_link': verified_upgrade_deadline_link(request.user, course=course), + 'on_course_outline_page': True, + 'missed_deadlines': missed_deadlines, + 'missed_gated_content': missed_gated_content, + 'has_ended': course.has_ended(), + } html = render_to_string('course_experience/course-outline-fragment.html', context) return Fragment(html)