Skip to content
Snippets Groups Projects
Commit bf7b3eab authored by Sanford Student's avatar Sanford Student
Browse files

add cert available date to CMS settings

parent 80538211
No related merge requests found
......@@ -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.');
}
......
......@@ -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: '',
......
......@@ -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() {
......
......@@ -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}'
</li>
</ol>
% if waffle.waffle().is_enabled(waffle.INSTRUCTOR_PACED_ONLY):
<ol class="list-input">
<li class="field-group field-group-certificate-available" id="certificate-available">
<div class="field date" id="field-certificate-available-date">
<label for="certificate-available-date">${_("Certificates Available Date")}</label>
<input type="text" class="certificate-available-date date start datepicker" id="certificate-available-date" placeholder="MM/DD/YYYY" autocomplete="off" />
<span class="tip tip-stacked">${_("By default, 48 hours after course end date")}</span>
</div>
</li>
</ol>
% endif
<ol class="list-input">
<li class="field-group field-group-enrollment-start" id="enrollment-start">
<div class="field date" id="field-enrollment-start-date">
......
......@@ -6,7 +6,6 @@ import logging
from django.db.models.signals import post_save
from django.dispatch import receiver
from .config import waffle
from certificates.models import \
CertificateGenerationCourseSetting, \
CertificateWhitelist, \
......@@ -14,6 +13,7 @@ from certificates.models import \
from certificates.tasks import generate_certificate
from courseware import courses
from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory
from openedx.core.djangoapps.certificates.config import waffle
from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED, LEARNER_NOW_VERIFIED
from student.models import CourseEnrollment
......
......@@ -5,7 +5,6 @@ and disabling for instructor-paced courses.
import mock
from certificates import api as certs_api
from certificates.config import waffle
from certificates.models import \
CertificateGenerationConfiguration, \
CertificateWhitelist, \
......@@ -15,6 +14,7 @@ from openedx.core.djangoapps.signals.handlers import _listen_for_course_pacing_c
from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory
from lms.djangoapps.grades.tests.utils import mock_passing_grade
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.certificates.config import waffle
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......
......@@ -106,6 +106,7 @@ class CourseDetails(object):
course_details = cls(course_key.org, course_key.course, course_key.run)
course_details.start_date = course_descriptor.start
course_details.end_date = course_descriptor.end
course_details.certificate_available_date = course_descriptor.certificate_available_date
course_details.enrollment_start = course_descriptor.enrollment_start
course_details.enrollment_end = course_descriptor.enrollment_end
course_details.pre_requisite_courses = course_descriptor.pre_requisite_courses
......@@ -233,6 +234,15 @@ class CourseDetails(object):
dirty = True
descriptor.enrollment_end = converted
if 'certificate_available_date' in jsondict:
converted = date.from_json(jsondict['certificate_available_date'])
else:
converted = None
if converted != descriptor.certificate_available_date:
dirty = True
descriptor.certificate_available_date = converted
if 'course_image_name' in jsondict and jsondict['course_image_name'] != descriptor.course_image:
descriptor.course_image = jsondict['course_image_name']
dirty = True
......
......@@ -39,6 +39,10 @@ class CourseDetailsTestCase(ModuleStoreTestCase):
self.assertIsNone(
details.enrollment_end, "enrollment_end date somehow initialized " + str(details.enrollment_end)
)
self.assertIsNone(
details.certificate_available_date,
"certificate_available_date date somehow initialized " + str(details.certificate_available_date)
)
self.assertIsNone(details.syllabus, "syllabus somehow initialized" + str(details.syllabus))
self.assertIsNone(details.intro_video, "intro_video somehow initialized" + str(details.intro_video))
self.assertIsNone(details.effort, "effort somehow initialized" + str(details.effort))
......@@ -90,6 +94,13 @@ class CourseDetailsTestCase(ModuleStoreTestCase):
CourseDetails.update_from_json(self.course.id, jsondetails.__dict__, self.user).end_date,
jsondetails.end_date
)
jsondetails.certificate_available_date = datetime.datetime(2010, 10, 1, 0, tzinfo=UTC())
self.assertEqual(
CourseDetails.update_from_json(
self.course.id, jsondetails.__dict__, self.user
).certificate_available_date,
jsondetails.certificate_available_date
)
jsondetails.course_image_name = "an_image.jpg"
self.assertEqual(
CourseDetails.update_from_json(self.course.id, jsondetails.__dict__, self.user).course_image_name,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment