diff --git a/common/djangoapps/course_modes/admin.py b/common/djangoapps/course_modes/admin.py index 1b3ad262e47f..1895fa2f2d46 100644 --- a/common/djangoapps/course_modes/admin.py +++ b/common/djangoapps/course_modes/admin.py @@ -125,6 +125,12 @@ def clean(self): mode_slug = cleaned_data.get("mode_slug") upgrade_deadline = cleaned_data.get("_expiration_datetime") verification_deadline = cleaned_data.get("verification_deadline") + expiration_datetime_is_explicit = cleaned_data.get("expiration_datetime_is_explicit") + + if expiration_datetime_is_explicit and upgrade_deadline is None: + raise forms.ValidationError( + "An upgrade deadline must be specified when setting Expiration datetime is explicit to True." + ) # Allow upgrade deadlines ONLY for the "verified" mode # This avoids a nasty error condition in which the upgrade deadline is set @@ -189,6 +195,7 @@ class CourseModeAdmin(admin.ModelAdmin): 'min_price', 'currency', '_expiration_datetime', + 'expiration_datetime_is_explicit', 'verification_deadline', 'sku', 'bulk_sku' diff --git a/common/djangoapps/course_modes/migrations/0014_auto_20221107_1559.py b/common/djangoapps/course_modes/migrations/0014_auto_20221107_1559.py new file mode 100644 index 000000000000..f8028d7c0c72 --- /dev/null +++ b/common/djangoapps/course_modes/migrations/0014_auto_20221107_1559.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.16 on 2022-11-07 15:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('course_modes', '0013_auto_20200115_2022'), + ] + + operations = [ + migrations.AlterField( + model_name='coursemode', + name='expiration_datetime_is_explicit', + field=models.BooleanField(default=False, help_text='OPTIONAL: Set to True if the upgrade deadline date is explicitly defined. Set to False if there is no upgrade deadline or to use the default upgrade deadline.', verbose_name='Upgrade Deadline Explicitly Defined'), + ), + migrations.AlterField( + model_name='historicalcoursemode', + name='expiration_datetime_is_explicit', + field=models.BooleanField(default=False, help_text='OPTIONAL: Set to True if the upgrade deadline date is explicitly defined. Set to False if there is no upgrade deadline or to use the default upgrade deadline.', verbose_name='Upgrade Deadline Explicitly Defined'), + ), + ] diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 0b015a133c9e..5d74a465d528 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -87,7 +87,14 @@ class CourseMode(models.Model): # The system prefers to set this automatically based on default settings. But # if the field is set manually we want a way to indicate that so we don't # overwrite the manual setting of the field. - expiration_datetime_is_explicit = models.BooleanField(default=False) + expiration_datetime_is_explicit = models.BooleanField( + default=False, + verbose_name=_("Upgrade Deadline Explicitly Defined"), + help_text=_( + "OPTIONAL: Set to True if the upgrade deadline date is explicitly defined. " + "Set to False if there is no upgrade deadline or to use the default upgrade deadline." + ) + ) # DEPRECATED: the `expiration_date` field has been replaced by `expiration_datetime` expiration_date = models.DateField(default=None, null=True, blank=True) diff --git a/common/djangoapps/course_modes/tests/test_admin.py b/common/djangoapps/course_modes/tests/test_admin.py index b1fe8b7ef7d9..e4d87536b5f7 100644 --- a/common/djangoapps/course_modes/tests/test_admin.py +++ b/common/djangoapps/course_modes/tests/test_admin.py @@ -164,6 +164,14 @@ def test_validate_upgrade_deadline_only_for_verified(self, course_mode): 'For other modes, please set the enrollment end date in Studio.' )) + def test_validate_expiration_datetime_is_explicit_only_with_upgrade_deadline(self): + # Only allow the expiration_datetime_is_explicit to be True if the upgrade_deadline is + # defined with a date, otherwise cause a validation error. + form = self._admin_form("verified", expiration_datetime_is_explicit=True) + self._assert_form_has_error(form, ( + "An upgrade deadline must be specified when setting Expiration datetime is explicit to True." + )) + @ddt.data("honor", "no-id-professional", "credit") def test_validate_verification_deadline_only_for_verified(self, course_mode): # Only the verified mode should have a verification deadline set. @@ -193,7 +201,7 @@ def _configure(self, mode, upgrade_deadline=None, verification_deadline=None): return CourseModeForm(instance=course_mode) - def _admin_form(self, mode, upgrade_deadline=None): + def _admin_form(self, mode, upgrade_deadline=None, expiration_datetime_is_explicit=False): """Load the course mode admin form. """ course_mode = CourseModeFactory.create( course_id=self.course.id, @@ -204,6 +212,7 @@ def _admin_form(self, mode, upgrade_deadline=None): "mode_slug": mode, "mode_display_name": mode, "_expiration_datetime": upgrade_deadline, + "expiration_datetime_is_explicit": expiration_datetime_is_explicit, "currency": "usd", "min_price": 10, }, instance=course_mode)