Files
edx-platform/openedx/core/djangoapps/schedules/models.py
Michael Terry 74887aa216 feat: turn on schedule creation by default
This commit removes several waffle toggles that have been enabled
on edx.org for years. It's time to remove the rollout gating for
these features and enable them by default.

This doesn't directly change any behavior. But it does create new
database objects by default now and allows for enabling other
schedule based features more easily.

Specifically, the following toggles were affected.

schedules.create_schedules_for_course
- Waffle flag removed as always-enabled
- We now always create a schedule when an enrollment is created

schedules.send_updates_for_course
- Waffle flag removed as always-enabled
- Course update emails are sent as long as the ScheduleConfig
  allows it.
- This is not a change in default behavior, because ScheduleConfig
  is off by default.

dynamic_pacing.studio_course_update
- Waffle switch removed as always-enabled
- Course teams can now always edit course updates directly in Studio

ScheduleConfig.create_schedules
ScheduleConfig.hold_back_ratio
- Model fields for rolling out the schedules feature
- Schedules are now always created
- This commit only removes references to these fields, they still
  exist in the database. A future commit will remove them entirely

This commit also adds a new has_highlights field to CourseOverview.
This is used to cache whether a course has highlights, used to
decide which course update email behavior they get. Previously every
enrollment had to dig into the modulestore to determine that.
2021-02-23 12:34:02 -05:00

78 lines
2.8 KiB
Python

# lint-amnesty, pylint: disable=missing-module-docstring
from config_models.models import ConfigurationModel
from django.contrib.sites.models import Site
from django.db import models
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices
from model_utils.models import TimeStampedModel
from simple_history.models import HistoricalRecords
class Schedule(TimeStampedModel):
"""
.. no_pii:
"""
enrollment = models.OneToOneField('student.CourseEnrollment', null=False, on_delete=models.CASCADE)
# The active field on the schedule is deprecated, please do not rely on it.
# You can use the is_active field on the CourseEnrollment model instead (i.e. schedule.enrollment.is_active).
# Removing this field from the database is a TODO for https://openedx.atlassian.net/browse/AA-574.
active = models.BooleanField(
default=True,
help_text=_('Indicates if this schedule is actively used')
)
start_date = models.DateTimeField(
db_index=True,
help_text=_('Date this schedule went into effect'),
null=True,
default=None
)
upgrade_deadline = models.DateTimeField(
blank=True,
db_index=True,
null=True,
help_text=_('Deadline by which the learner must upgrade to a verified seat')
)
history = HistoricalRecords()
def get_experience_type(self):
try:
return self.experience.experience_type
except ScheduleExperience.DoesNotExist:
return ScheduleExperience.EXPERIENCES.default
class Meta(object):
verbose_name = _('Schedule')
verbose_name_plural = _('Schedules')
class ScheduleConfig(ConfigurationModel):
"""
.. no_pii:
"""
KEY_FIELDS = ('site',)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
create_schedules = models.BooleanField(default=False) # deprecated, do not use
enqueue_recurring_nudge = models.BooleanField(default=False)
deliver_recurring_nudge = models.BooleanField(default=False)
enqueue_upgrade_reminder = models.BooleanField(default=False)
deliver_upgrade_reminder = models.BooleanField(default=False)
enqueue_course_update = models.BooleanField(default=False)
deliver_course_update = models.BooleanField(default=False)
hold_back_ratio = models.FloatField(default=0) # deprecated, do not use
class ScheduleExperience(models.Model):
"""
.. no_pii:
"""
EXPERIENCES = Choices(
(0, 'default', u'Recurring Nudge and Upgrade Reminder'),
(1, 'course_updates', u'Course Updates')
)
schedule = models.OneToOneField(Schedule, related_name='experience', on_delete=models.CASCADE)
experience_type = models.PositiveSmallIntegerField(choices=EXPERIENCES, default=EXPERIENCES.default)