add cert available date to CMS settings
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user