Commit 1e1b321b by Diana Huang

Merge pull request #4655 from edx/diana/allow-only-verified

Allow verified to be offered without audit
parents ea4e76b0 ec13aabe
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'CourseMode.description'
db.add_column('course_modes_coursemode', 'description',
self.gf('django.db.models.fields.TextField')(null=True, blank=True),
keep_default=False)
# Changing field 'CourseMode.course_id'
db.alter_column('course_modes_coursemode', 'course_id', self.gf('xmodule_django.models.CourseKeyField')(max_length=255))
def backwards(self, orm):
# Deleting field 'CourseMode.description'
db.delete_column('course_modes_coursemode', 'description')
# Changing field 'CourseMode.course_id'
db.alter_column('course_modes_coursemode', 'course_id', self.gf('django.db.models.fields.CharField')(max_length=255))
models = {
'course_modes.coursemode': {
'Meta': {'unique_together': "(('course_id', 'mode_slug', 'currency'),)", 'object_name': 'CourseMode'},
'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
'currency': ('django.db.models.fields.CharField', [], {'default': "'usd'", 'max_length': '8'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'expiration_date': ('django.db.models.fields.DateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'expiration_datetime': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'min_price': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'mode_display_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'mode_slug': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'suggested_prices': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'default': "''", 'max_length': '255', 'blank': 'True'})
}
}
complete_apps = ['course_modes']
\ No newline at end of file
......@@ -11,7 +11,17 @@ from django.db.models import Q
from xmodule_django.models import CourseKeyField
Mode = namedtuple('Mode', ['slug', 'name', 'min_price', 'suggested_prices', 'currency', 'expiration_datetime'])
Mode = namedtuple('Mode',
[
'slug',
'name',
'min_price',
'suggested_prices',
'currency',
'expiration_datetime',
'description'
])
class CourseMode(models.Model):
"""
......@@ -42,7 +52,11 @@ class CourseMode(models.Model):
expiration_datetime = models.DateTimeField(default=None, null=True, blank=True)
DEFAULT_MODE = Mode('honor', _('Honor Code Certificate'), 0, '', 'usd', None)
# optional description override
# WARNING: will not be localized
description = models.TextField(null=True, blank=True)
DEFAULT_MODE = Mode('honor', _('Honor Code Certificate'), 0, '', 'usd', None, None)
DEFAULT_MODE_SLUG = 'honor'
class Meta:
......@@ -66,7 +80,8 @@ class CourseMode(models.Model):
mode.min_price,
mode.suggested_prices,
mode.currency,
mode.expiration_datetime
mode.expiration_datetime,
mode.description
) for mode in found_course_modes])
if not modes:
modes = [cls.DEFAULT_MODE]
......
......@@ -50,7 +50,7 @@ class CourseModeModelTest(TestCase):
self.create_mode('verified', 'Verified Certificate')
modes = CourseMode.modes_for_course(self.course_key)
mode = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None)
mode = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None, None)
self.assertEqual([mode], modes)
modes_dict = CourseMode.modes_for_course_dict(self.course_key)
......@@ -62,8 +62,8 @@ class CourseModeModelTest(TestCase):
"""
Finding the modes when there's multiple modes
"""
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None)
mode2 = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None)
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None)
mode2 = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None, None)
set_modes = [mode1, mode2]
for mode in set_modes:
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices)
......@@ -82,9 +82,9 @@ class CourseModeModelTest(TestCase):
self.assertEqual(0, CourseMode.min_course_price_for_currency(self.course_key, 'usd'))
# create some modes
mode1 = Mode(u'honor', u'Honor Code Certificate', 10, '', 'usd', None)
mode2 = Mode(u'verified', u'Verified Certificate', 20, '', 'usd', None)
mode3 = Mode(u'honor', u'Honor Code Certificate', 80, '', 'cny', None)
mode1 = Mode(u'honor', u'Honor Code Certificate', 10, '', 'usd', None, None)
mode2 = Mode(u'verified', u'Verified Certificate', 20, '', 'usd', None, None)
mode3 = Mode(u'honor', u'Honor Code Certificate', 80, '', 'cny', None, None)
set_modes = [mode1, mode2, mode3]
for mode in set_modes:
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices, mode.currency)
......@@ -99,7 +99,7 @@ class CourseModeModelTest(TestCase):
modes = CourseMode.modes_for_course(self.course_key)
self.assertEqual([CourseMode.DEFAULT_MODE], modes)
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None)
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None)
self.create_mode(mode1.slug, mode1.name, mode1.min_price, mode1.suggested_prices)
modes = CourseMode.modes_for_course(self.course_key)
self.assertEqual([mode1], modes)
......@@ -107,7 +107,7 @@ class CourseModeModelTest(TestCase):
expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=1)
expired_mode.expiration_datetime = expiration_datetime
expired_mode.save()
expired_mode_value = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', expiration_datetime)
expired_mode_value = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', expiration_datetime, None)
modes = CourseMode.modes_for_course(self.course_key)
self.assertEqual([expired_mode_value, mode1], modes)
......
......@@ -60,6 +60,7 @@ class ChooseModeView(View):
"chosen_price": chosen_price,
"error": error,
"upgrade": upgrade,
"can_audit": "audit" in modes,
}
if "verified" in modes:
context["suggested_prices"] = [
......@@ -69,6 +70,8 @@ class ChooseModeView(View):
]
context["currency"] = modes["verified"].currency.upper()
context["min_price"] = modes["verified"].min_price
context["verified_name"] = modes["verified"].name
context["verified_description"] = modes["verified"].description
return render_to_response("course_modes/choose.html", context)
......
......@@ -632,10 +632,16 @@ def change_enrollment(request):
available_modes = CourseMode.modes_for_course(course_id)
if len(available_modes) > 1:
return HttpResponse(
reverse("course_modes_choose", kwargs={'course_id': course_id.to_deprecated_string()})
reverse("course_modes_choose", kwargs={'course_id': unicode(course_id)})
)
current_mode = available_modes[0]
# only automatically enroll people if the only mode is 'honor'
if current_mode.slug != 'honor':
return HttpResponse(
reverse("course_modes_choose", kwargs={'course_id': unicode(course_id)})
)
CourseEnrollment.enroll(user, course.id, mode=current_mode.slug)
return HttpResponse()
......
......@@ -66,17 +66,27 @@ $(document).ready(function() {
<div class="register-choice register-choice-certificate">
<div class="wrapper-copy">
<span class="deco-ribbon"></span>
<h4 class="title">${_("Certificate of Achievement (ID Verified)")}</h4>
%if upgrade:
<div class="copy">
<p>${_("Upgrade and work toward a verified Certificate of Achievement.")}</p>
</div>
%if verified_name == "Verified Certificate":
<h4 class="title">${_("Certificate of Achievement (ID Verified)")}</h4>
%else:
<div class="copy">
<p>${_("Sign up and work toward a verified Certificate of Achievement.")}</p>
</div>
<h4 class="title">${verified_name}</h4>
%endif
%if verified_name == "Verified Certificate":
%if upgrade:
<div class="copy">
<p>${_("Upgrade and work toward a verified Certificate of Achievement.")}</p>
</div>
%else:
<div class="copy">
<p>${_("Sign up and work toward a verified Certificate of Achievement.")}</p>
</div>
%endif
%else:
<div class="copy">
<p>${verified_description}</p>
</div>
%endif
</div>
<div class="field field-certificate-contribution">
......
......@@ -74,7 +74,8 @@ class VerifyView(View):
# bookkeeping-wise just to start over.
progress_state = "start"
verify_mode = CourseMode.mode_for_course(course_id, "verified")
modes_dict = CourseMode.modes_for_course_dict(course_id)
verify_mode = modes_dict.get('verified', None)
# if the course doesn't have a verified mode, we want to kick them
# from the flow
if not verify_mode:
......@@ -102,6 +103,7 @@ class VerifyView(View):
"chosen_price": chosen_price,
"min_price": verify_mode.min_price,
"upgrade": upgrade,
"can_audit": "audit" in modes_dict,
}
return render_to_response('verify_student/photo_verification.html', context)
......@@ -121,7 +123,9 @@ class VerifiedView(View):
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
if CourseEnrollment.enrollment_mode_for_user(request.user, course_id) == ('verified', True):
return redirect(reverse('dashboard'))
verify_mode = CourseMode.mode_for_course(course_id, "verified")
modes_dict = CourseMode.modes_for_course_dict(course_id)
verify_mode = modes_dict.get('verified', None)
if verify_mode is None:
return redirect(reverse('dashboard'))
......@@ -146,6 +150,7 @@ class VerifiedView(View):
"chosen_price": chosen_price,
"create_order_url": reverse("verify_student_create_order"),
"upgrade": upgrade,
"can_audit": "audit" in modes_dict,
}
return render_to_response('verify_student/verified.html', context)
......
......@@ -10,6 +10,7 @@
</div>
</li>
%if can_audit:
<li class="help-item help-item-coldfeet">
%if upgrade:
<h3 class="title">${_("Change your mind?")}</h3>
......@@ -23,6 +24,7 @@
</div>
%endif
</li>
%endif
<li class="help-item help-item-technical">
<h3 class="title">${_("Technical Requirements")}</h3>
......
......@@ -156,11 +156,13 @@
<nav class="nav-wizard ${"is-not-ready" if is_not_active else "is-ready"}">
%if can_audit:
%if upgrade:
<span class="help help-inline">${_("Missing something? You can always continue to audit this course instead.")}</span>
%else:
<span class="help help-inline">${_("Missing something? You can always {a_start}audit this course instead{a_end}").format(a_start='<a href="{}">'.format(course_modes_choose_url), a_end="</a>")}</span>
%endif
%endif
<ol class="wizard-steps">
<li class="wizard-step">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment