From 309cadc973ca85e22324e6f60dcadefd17307856 Mon Sep 17 00:00:00 2001
From: David Ormsbee <dormsbee@edx.org>
Date: Wed, 8 Sep 2021 11:05:35 -0400
Subject: [PATCH] Revert "Use new version of edx-when." (#28684)

Reverting because of errors seen in proctoring. The error from splunk:

 File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/edx_proctoring/views.py", line 590, in get
    data['onboarding_release_date'] = effective_start.isoformat()
AttributeError: 'NoneType' object has no attribute 'isoformat'

The effective date is coming from learning_sequences, which ultimately
comes from edx-when.
---
 lms/djangoapps/course_api/api.py                  | 11 -----------
 lms/djangoapps/courseware/tests/test_views.py     |  4 ++--
 lms/djangoapps/instructor/views/api.py            |  4 +---
 lms/djangoapps/instructor/views/tools.py          | 12 ++++--------
 .../content/learning_sequences/api/outlines.py    |  2 +-
 .../learning_sequences/api/processors/base.py     |  8 +++-----
 .../api/processors/content_gating.py              |  2 +-
 .../enrollment_track_partition_groups.py          |  8 ++------
 .../learning_sequences/api/processors/schedule.py | 15 +++++----------
 .../api/processors/special_exams.py               |  2 +-
 .../learning_sequences/api/tests/test_outlines.py |  6 ++----
 requirements/edx/base.txt                         |  2 +-
 requirements/edx/development.txt                  |  2 +-
 requirements/edx/testing.txt                      |  2 +-
 14 files changed, 25 insertions(+), 55 deletions(-)

diff --git a/lms/djangoapps/course_api/api.py b/lms/djangoapps/course_api/api.py
index 6b0ae672c64..87deb133d48 100644
--- a/lms/djangoapps/course_api/api.py
+++ b/lms/djangoapps/course_api/api.py
@@ -22,8 +22,6 @@ from lms.djangoapps.courseware.courses import (
     get_permission_for_course_about
 )
 from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
-from openedx.core.djangoapps.content.learning_sequences.api import get_course_outline
-from openedx.core.djangoapps.content.learning_sequences.data import CourseOutlineData
 from openedx.core.lib.api.view_utils import LazySequence
 from xmodule.modulestore.django import modulestore
 from xmodule.modulestore.exceptions import ItemNotFoundError
@@ -237,18 +235,9 @@ def get_due_dates(request, course_key, user):
                 url: the deep link to the block
                 date: the due date for the block
     """
-    try:
-        outline = get_course_outline(course_key)
-    except (ValueError, CourseOutlineData.DoesNotExist):
-        # Either this course is Old Mongo-backed or doesn't have a generated course outline.
-        course_version = None
-    else:
-        course_version = outline.published_version
-
     dates = get_dates_for_course(
         course_key,
         user,
-        published_version=course_version
     )
 
     store = modulestore()
diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py
index f3e9fc10179..c3b46364f50 100644
--- a/lms/djangoapps/courseware/tests/test_views.py
+++ b/lms/djangoapps/courseware/tests/test_views.py
@@ -1559,8 +1559,8 @@ class ProgressPageTests(ProgressPageBaseTests):
 
     @patch.dict(settings.FEATURES, {'ASSUME_ZERO_GRADE_IF_ABSENT_FOR_ALL_TESTS': False})
     @ddt.data(
-        (False, 63, 44),
-        (True, 55, 38)
+        (False, 63, 46),
+        (True, 55, 40)
     )
     @ddt.unpack
     def test_progress_queries(self, enable_waffle, initial, subsequent):
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index 359ce86cfe3..e431e6b39cf 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -2740,9 +2740,7 @@ def reset_due_date(request, course_id):
     unit = find_unit(course, request.POST.get('url'))
     reason = strip_tags(request.POST.get('reason', ''))
 
-    version = getattr(course, 'course_version', None)
-
-    original_due_date = get_date_for_block(course_id, unit.location, published_version=version)
+    original_due_date = get_date_for_block(course_id, unit.location)
 
     set_due_date_extension(course, unit, student, None, request.user, reason=reason)
     if not original_due_date:
diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py
index 62c95e1a71b..ea40d4d5360 100644
--- a/lms/djangoapps/instructor/views/tools.py
+++ b/lms/djangoapps/instructor/views/tools.py
@@ -125,13 +125,11 @@ def get_units_with_due_date(course):
     """
     units = []
 
-    version = getattr(course, 'course_version', None)
-
     # Pass in a schedule here so that we get back any relative dates in the course, but actual value
     # doesn't matter, since we don't care about the dates themselves, just whether they exist.
     # Thus we don't save or care about this temporary schedule object.
     schedule = Schedule(start_date=course.start)
-    course_dates = api.get_dates_for_course(course.id, schedule=schedule, published_version=version)
+    course_dates = api.get_dates_for_course(course.id, schedule=schedule)
 
     def visit(node):
         """
@@ -175,8 +173,7 @@ def set_due_date_extension(course, unit, student, due_date, actor=None, reason='
     # We normally set dates at the subsection level. But technically dates can be anywhere down the tree (and
     # usually are in self paced courses, where the subsection date gets propagated down).
     # So find all children that we need to set the date on, then set those dates.
-    version = getattr(course, 'course_version', None)
-    course_dates = api.get_dates_for_course(course.id, user=student, published_version=version)
+    course_dates = api.get_dates_for_course(course.id, user=student)
     blocks_to_set = {unit}  # always include the requested unit, even if it doesn't appear to have a due date now
 
     def visit(node):
@@ -194,9 +191,8 @@ def set_due_date_extension(course, unit, student, due_date, actor=None, reason='
     for block in blocks_to_set:
         if due_date:
             try:
-                api.set_date_for_block(
-                    course.id, block.location, 'due', due_date, user=student, reason=reason, actor=actor
-                )
+                api.set_date_for_block(course.id, block.location, 'due', due_date, user=student, reason=reason,
+                                       actor=actor)
             except api.MissingDateError as ex:
                 raise DashboardError(_("Unit {0} has no due date to extend.").format(unit.location)) from ex
             except api.InvalidDateError as ex:
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/outlines.py b/openedx/core/djangoapps/content/learning_sequences/api/outlines.py
index a787836c68e..218fd7d504c 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/outlines.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/outlines.py
@@ -356,7 +356,7 @@ def _get_user_course_outline_and_processors(course_key: CourseKey,  # lint-amnes
         # particular ordering).
         processor = processor_cls(course_key, user, at_time)
         processors[name] = processor
-        processor.load_data(full_course_outline)
+        processor.load_data()
         if not user_can_see_all_content:
             # function_trace lets us see how expensive each processor is being.
             with function_trace(f'learning_sequences.api.outline_processors.{name}'):
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py
index 72762667bfa..54182b28251 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/base.py
@@ -8,8 +8,6 @@ from datetime import datetime
 from opaque_keys.edx.keys import CourseKey  # lint-amnesty, pylint: disable=unused-import
 from openedx.core import types
 
-from ...data import CourseOutlineData
-
 log = logging.getLogger(__name__)
 
 
@@ -46,7 +44,7 @@ class OutlineProcessor:
         self.user = user
         self.at_time = at_time
 
-    def load_data(self, full_course_outline: CourseOutlineData):  # pylint: disable=unused-argument
+    def load_data(self):
         """
         Fetch whatever data you need about the course and user here.
 
@@ -61,7 +59,7 @@ class OutlineProcessor:
         """
         pass  # lint-amnesty, pylint: disable=unnecessary-pass
 
-    def inaccessible_sequences(self, full_course_outline: CourseOutlineData):  # pylint: disable=unused-argument
+    def inaccessible_sequences(self, full_course_outline):  # lint-amnesty, pylint: disable=unused-argument
         """
         Return a set/frozenset of Sequence UsageKeys that are not accessible.
 
@@ -70,7 +68,7 @@ class OutlineProcessor:
         """
         return frozenset()
 
-    def usage_keys_to_remove(self, full_course_outline: CourseOutlineData):  # pylint: disable=unused-argument
+    def usage_keys_to_remove(self, full_course_outline):  # lint-amnesty, pylint: disable=unused-argument
         """
         Return a set/frozenset of UsageKeys to remove altogether.
 
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py
index 9f86406dd97..a18a1fa5b7f 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/content_gating.py
@@ -27,7 +27,7 @@ class ContentGatingOutlineProcessor(OutlineProcessor):
         self.required_content = None
         self.can_skip_entrance_exam = False
 
-    def load_data(self, full_course_outline):
+    def load_data(self):
         """
         Get the required content for the course, and whether
         or not the user can skip the entrance exam.
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/enrollment_track_partition_groups.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/enrollment_track_partition_groups.py
index da58085ac7e..82fed385994 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/processors/enrollment_track_partition_groups.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/enrollment_track_partition_groups.py
@@ -1,9 +1,5 @@
 # lint-amnesty, pylint: disable=missing-module-docstring
 import logging
-from datetime import datetime
-
-from opaque_keys.edx.keys import CourseKey
-from openedx.core import types
 
 from xmodule.partitions.enrollment_track_partition_generator import (
     create_enrollment_track_partition_with_course_id
@@ -26,12 +22,12 @@ class EnrollmentTrackPartitionGroupsOutlineProcessor(OutlineProcessor):
     significant limitation. Nonetheless, it is a step towards the goal of
     supporting all partition schemes in the future.
     """
-    def __init__(self, course_key: CourseKey, user: types.User, at_time: datetime):
+    def __init__(self, course_key, user, at_time):
         super().__init__(course_key, user, at_time)
         self.enrollment_track_groups = {}
         self.user_group = None
 
-    def load_data(self, full_course_outline):
+    def load_data(self):
         """
         Pull track groups for this course and which group the user is in.
         """
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py
index 643559e51a9..024c17e3c2d 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/schedule.py
@@ -42,16 +42,11 @@ class ScheduleOutlineProcessor(OutlineProcessor):
         self._course_end = None
         self._is_beta_tester = False
 
-    def load_data(self, full_course_outline):
-        """
-        Pull dates information from edx-when.
-
-        Return data format: (usage_key, 'due'): datetime.datetime(2019, 12, 11, 15, 0, tzinfo=<UTC>)
-        """
-        self.dates = get_dates_for_course(
-            self.course_key, self.user, subsection_and_higher_only=True,
-            published_version=full_course_outline.published_version
-        )
+    def load_data(self):
+        """Pull dates information from edx-when."""
+        # (usage_key, 'due'): datetime.datetime(2019, 12, 11, 15, 0, tzinfo=<UTC>)
+        # TODO: Merge https://github.com/edx/edx-when/pull/48 and add `outline_only=True`
+        self.dates = get_dates_for_course(self.course_key, self.user)
 
         for (usage_key, field_name), date in self.dates.items():
             self.keys_to_schedule_fields[usage_key][field_name] = date
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py b/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py
index 1fa7c97cf51..67d4ad8350c 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/processors/special_exams.py
@@ -28,7 +28,7 @@ class SpecialExamsOutlineProcessor(OutlineProcessor):
     """
     Responsible for applying all outline processing related to special exams.
     """
-    def load_data(self, full_course_outline):
+    def load_data(self):
         """
         Check if special exams are enabled
         """
diff --git a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py
index bd3080b3fc3..89438d9a17d 100644
--- a/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py
+++ b/openedx/core/djangoapps/content/learning_sequences/api/tests/test_outlines.py
@@ -1737,10 +1737,8 @@ class EnrollmentTrackPartitionGroupsTestCase(OutlineProcessorTestCase):  # lint-
 
         check_date = datetime(2021, 3, 27, tzinfo=timezone.utc)
         for learner_to_verify in learners_to_verify:
-            processor = EnrollmentTrackPartitionGroupsOutlineProcessor(
-                self.course_key, learner_to_verify, check_date
-            )
-            processor.load_data(full_outline)
+            processor = EnrollmentTrackPartitionGroupsOutlineProcessor(self.course_key, learner_to_verify, check_date)
+            processor.load_data()
             removed_usage_keys = processor.usage_keys_to_remove(full_outline)
             assert len(removed_usage_keys) == expected_values_dict[learner_to_verify.username]
 
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index 16450a60c16..ed19843f705 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -509,7 +509,7 @@ edx-toggles==4.2.0
     #   ora2
 edx-user-state-client==1.3.2
     # via -r requirements/edx/base.in
-edx-when==2.2.0
+edx-when==2.1.0
     # via
     #   -r requirements/edx/base.in
     #   edx-proctoring
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index a4a9e52b93e..5916e018377 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -619,7 +619,7 @@ edx-toggles==4.2.0
     #   ora2
 edx-user-state-client==1.3.2
     # via -r requirements/edx/testing.txt
-edx-when==2.2.0
+edx-when==2.1.0
     # via
     #   -r requirements/edx/testing.txt
     #   edx-proctoring
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index a4625a87be3..040842a6ac1 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -599,7 +599,7 @@ edx-toggles==4.2.0
     #   ora2
 edx-user-state-client==1.3.2
     # via -r requirements/edx/base.txt
-edx-when==2.2.0
+edx-when==2.1.0
     # via
     #   -r requirements/edx/base.txt
     #   edx-proctoring
-- 
GitLab