diff --git a/cms/static/js/models/settings/course_details.js b/cms/static/js/models/settings/course_details.js index 683200d7d6..a6a81bfa10 100644 --- a/cms/static/js/models/settings/course_details.js +++ b/cms/static/js/models/settings/course_details.js @@ -8,6 +8,7 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js language: '', start_date: null, // maps to 'start' end_date: null, // maps to 'end' + certificate_available_date: null, enrollment_start: null, enrollment_end: null, syllabus: null, @@ -38,7 +39,7 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js // A bit funny in that the video key validation is asynchronous; so, it won't stop the validation. var errors = {}; newattrs = DateUtils.convertDateStringsToObjects( - newattrs, ['start_date', 'end_date', 'enrollment_start', 'enrollment_end'] + newattrs, ['start_date', 'end_date', 'certificate_available_date', 'enrollment_start', 'enrollment_end'] ); if (newattrs.start_date === null) { @@ -51,6 +52,14 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js if (newattrs.start_date && newattrs.enrollment_start && newattrs.start_date < newattrs.enrollment_start) { errors.enrollment_start = gettext('The course start date must be later than the enrollment start date.'); } + if ( + newattrs.start_date && newattrs.certificate_available_date && newattrs.start_date > + newattrs.certificate_available_date + ) { + errors.enrollment_start = gettext( + 'The certificate available date must be later than the enrollment start date.' + ); + } if (newattrs.enrollment_start && newattrs.enrollment_end && newattrs.enrollment_start >= newattrs.enrollment_end) { errors.enrollment_end = gettext('The enrollment start date cannot be after the enrollment end date.'); } diff --git a/cms/static/js/spec/views/settings/main_spec.js b/cms/static/js/spec/views/settings/main_spec.js index 4fbebcc84d..e33e845465 100644 --- a/cms/static/js/spec/views/settings/main_spec.js +++ b/cms/static/js/spec/views/settings/main_spec.js @@ -21,6 +21,7 @@ define([ end_date: '2014-11-05T20:00:00Z', enrollment_start: '2014-10-00T00:00:00Z', enrollment_end: '2014-11-05T00:00:00Z', + certificate_available_date: '2014-11-05T20:00:00Z', org: '', course_id: '', run: '', diff --git a/cms/static/js/views/settings/main.js b/cms/static/js/views/settings/main.js index 8125c0a936..0b9204a8e1 100644 --- a/cms/static/js/views/settings/main.js +++ b/cms/static/js/views/settings/main.js @@ -79,6 +79,7 @@ define(['js/views/validation', 'codemirror', 'underscore', 'jquery', 'jquery.ui' DateUtils.setupDatePicker('start_date', this); DateUtils.setupDatePicker('end_date', this); + DateUtils.setupDatePicker('certificate_available_date', this); DateUtils.setupDatePicker('enrollment_start', this); DateUtils.setupDatePicker('enrollment_end', this); @@ -154,29 +155,30 @@ define(['js/views/validation', 'codemirror', 'underscore', 'jquery', 'jquery.ui' return this; }, fieldToSelectorMap: { - 'language': 'course-language', - 'start_date': 'course-start', - 'end_date': 'course-end', - 'enrollment_start': 'enrollment-start', - 'enrollment_end': 'enrollment-end', - 'overview': 'course-overview', - 'title': 'course-title', - 'subtitle': 'course-subtitle', - 'duration': 'course-duration', - 'description': 'course-description', - 'short_description': 'course-short-description', - 'intro_video': 'course-introduction-video', - 'effort': 'course-effort', - 'course_image_asset_path': 'course-image-url', - 'banner_image_asset_path': 'banner-image-url', - 'video_thumbnail_image_asset_path': 'video-thumbnail-image-url', - 'pre_requisite_courses': 'pre-requisite-course', - 'entrance_exam_enabled': 'entrance-exam-enabled', - 'entrance_exam_minimum_score_pct': 'entrance-exam-minimum-score-pct', - 'course_settings_learning_fields': 'course-settings-learning-fields', - 'add_course_learning_info': 'add-course-learning-info', - 'add_course_instructor_info': 'add-course-instructor-info', - 'course_learning_info': 'course-learning-info' + language: 'course-language', + start_date: 'course-start', + end_date: 'course-end', + enrollment_start: 'enrollment-start', + enrollment_end: 'enrollment-end', + certificate_available_date: 'certificate-available', + overview: 'course-overview', + title: 'course-title', + subtitle: 'course-subtitle', + duration: 'course-duration', + description: 'course-description', + short_description: 'course-short-description', + intro_video: 'course-introduction-video', + effort: 'course-effort', + course_image_asset_path: 'course-image-url', + banner_image_asset_path: 'banner-image-url', + video_thumbnail_image_asset_path: 'video-thumbnail-image-url', + pre_requisite_courses: 'pre-requisite-course', + entrance_exam_enabled: 'entrance-exam-enabled', + entrance_exam_minimum_score_pct: 'entrance-exam-minimum-score-pct', + course_settings_learning_fields: 'course-settings-learning-fields', + add_course_learning_info: 'add-course-learning-info', + add_course_instructor_info: 'add-course-instructor-info', + course_learning_info: 'course-learning-info' }, addLearningFields: function() { diff --git a/cms/templates/settings.html b/cms/templates/settings.html index 2a5c51b887..420b6975f8 100644 --- a/cms/templates/settings.html +++ b/cms/templates/settings.html @@ -9,6 +9,7 @@ import urllib from django.utils.translation import ugettext as _ from contentstore import utils + from openedx.core.djangoapps.certificates.config import waffle from openedx.core.djangolib.js_utils import ( dump_js_escaped_json, js_escaped_string ) @@ -213,6 +214,18 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url | n, js_escaped_string}' + % if waffle.waffle().is_enabled(waffle.INSTRUCTOR_PACED_ONLY): +