Commit ea8a56da by Brian Wilson

add id generation and validation

parent e32dfcf0
...@@ -8,29 +8,15 @@ from django.db import models ...@@ -8,29 +8,15 @@ from django.db import models
class Migration(SchemaMigration): class Migration(SchemaMigration):
def forwards(self, orm): def forwards(self, orm):
# Adding field 'TestCenterUser.upload_status'
db.add_column('student_testcenteruser', 'upload_status',
self.gf('django.db.models.fields.CharField')(default='', max_length=20, blank=True),
keep_default=False)
# Adding field 'TestCenterUser.uploaded_at'
db.add_column('student_testcenteruser', 'uploaded_at',
self.gf('django.db.models.fields.DateTimeField')(null=True, db_index=True),
keep_default=False)
# Adding field 'TestCenterUser.upload_error_message'
db.add_column('student_testcenteruser', 'upload_error_message',
self.gf('django.db.models.fields.CharField')(default='', max_length=512, blank=True),
keep_default=False)
# Adding model 'TestCenterRegistration' # Adding model 'TestCenterRegistration'
db.create_table('student_testcenterregistration', ( db.create_table('student_testcenterregistration', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('testcenter_user', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['student.TestCenterUser'], unique=True)), ('testcenter_user', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['student.TestCenterUser'])),
('course_id', self.gf('django.db.models.fields.CharField')(max_length=128, db_index=True)), ('course_id', self.gf('django.db.models.fields.CharField')(max_length=128, db_index=True)),
('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)), ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)),
('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, db_index=True, blank=True)), ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, db_index=True, blank=True)),
('user_updated_at', self.gf('django.db.models.fields.DateTimeField')(db_index=True)), ('user_updated_at', self.gf('django.db.models.fields.DateTimeField')(db_index=True)),
('client_authorization_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=20, db_index=True)),
('exam_series_code', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)), ('exam_series_code', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)),
('eligibility_appointment_date_first', self.gf('django.db.models.fields.DateField')(db_index=True)), ('eligibility_appointment_date_first', self.gf('django.db.models.fields.DateField')(db_index=True)),
('eligibility_appointment_date_last', self.gf('django.db.models.fields.DateField')(db_index=True)), ('eligibility_appointment_date_last', self.gf('django.db.models.fields.DateField')(db_index=True)),
...@@ -42,8 +28,35 @@ class Migration(SchemaMigration): ...@@ -42,8 +28,35 @@ class Migration(SchemaMigration):
)) ))
db.send_create_signal('student', ['TestCenterRegistration']) db.send_create_signal('student', ['TestCenterRegistration'])
# Adding field 'TestCenterUser.upload_status'
db.add_column('student_testcenteruser', 'upload_status',
self.gf('django.db.models.fields.CharField')(db_index=True, default='', max_length=20, blank=True),
keep_default=False)
# Adding field 'TestCenterUser.uploaded_at'
db.add_column('student_testcenteruser', 'uploaded_at',
self.gf('django.db.models.fields.DateTimeField')(db_index=True, null=True, blank=True),
keep_default=False)
# Adding field 'TestCenterUser.upload_error_message'
db.add_column('student_testcenteruser', 'upload_error_message',
self.gf('django.db.models.fields.CharField')(default='', max_length=512, blank=True),
keep_default=False)
# Adding index on 'TestCenterUser', fields ['company_name']
db.create_index('student_testcenteruser', ['company_name'])
# Adding unique constraint on 'TestCenterUser', fields ['client_candidate_id']
db.create_unique('student_testcenteruser', ['client_candidate_id'])
def backwards(self, orm): def backwards(self, orm):
# Removing unique constraint on 'TestCenterUser', fields ['client_candidate_id']
db.delete_unique('student_testcenteruser', ['client_candidate_id'])
# Removing index on 'TestCenterUser', fields ['company_name']
db.delete_index('student_testcenteruser', ['company_name'])
# Deleting model 'TestCenterRegistration' # Deleting model 'TestCenterRegistration'
db.delete_table('student_testcenterregistration') db.delete_table('student_testcenterregistration')
...@@ -126,17 +139,17 @@ class Migration(SchemaMigration): ...@@ -126,17 +139,17 @@ class Migration(SchemaMigration):
'accommodation_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 'accommodation_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'accommodation_request': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}), 'accommodation_request': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
'client_authorization_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}), 'client_authorization_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'db_index': 'True'}),
'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), 'course_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'eligibility_appointment_date_first': ('django.db.models.fields.DateField', [], {'db_index': 'True'}), 'eligibility_appointment_date_first': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
'eligibility_appointment_date_last': ('django.db.models.fields.DateField', [], {'db_index': 'True'}), 'eligibility_appointment_date_last': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
'exam_series_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}), 'exam_series_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'testcenter_user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['student.TestCenterUser']", 'unique': 'True'}), 'testcenter_user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['student.TestCenterUser']"}),
'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
'upload_error_message': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 'upload_error_message': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'upload_status': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), 'upload_status': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'user_updated_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}) 'user_updated_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'})
}, },
'student.testcenteruser': { 'student.testcenteruser': {
...@@ -146,9 +159,8 @@ class Migration(SchemaMigration): ...@@ -146,9 +159,8 @@ class Migration(SchemaMigration):
'address_3': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}), 'address_3': ('django.db.models.fields.CharField', [], {'max_length': '40', 'blank': 'True'}),
'candidate_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_index': 'True'}), 'candidate_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'db_index': 'True'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
'client_candidate_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}), 'client_candidate_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}),
'company_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), 'company_name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),
'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '3', 'db_index': 'True'}), 'country': ('django.db.models.fields.CharField', [], {'max_length': '3', 'db_index': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'extension': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '8', 'blank': 'True'}), 'extension': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '8', 'blank': 'True'}),
...@@ -166,7 +178,8 @@ class Migration(SchemaMigration): ...@@ -166,7 +178,8 @@ class Migration(SchemaMigration):
'suffix': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), 'suffix': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
'upload_error_message': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 'upload_error_message': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
'upload_status': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), 'upload_status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '20', 'blank': 'True'}),
'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['auth.User']", 'unique': 'True'}), 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['auth.User']", 'unique': 'True'}),
'user_updated_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}) 'user_updated_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'})
}, },
...@@ -194,4 +207,4 @@ class Migration(SchemaMigration): ...@@ -194,4 +207,4 @@ class Migration(SchemaMigration):
} }
} }
complete_apps = ['student'] complete_apps = ['student']
\ No newline at end of file
...@@ -18,18 +18,17 @@ from django.contrib.auth.models import User ...@@ -18,18 +18,17 @@ from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.core.mail import send_mail from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.core.validators import validate_email, validate_slug, ValidationError from django.core.validators import validate_email, validate_slug, ValidationError
from django.db import IntegrityError from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseForbidden, Http404,\ from django.http import HttpResponse, HttpResponseForbidden, Http404
HttpResponseRedirect
from django.shortcuts import redirect from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string from mitxmako.shortcuts import render_to_response, render_to_string
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from django.core.cache import cache from django.core.cache import cache
from django_future.csrf import ensure_csrf_cookie, csrf_exempt from django_future.csrf import ensure_csrf_cookie, csrf_exempt
from student.models import (Registration, UserProfile, TestCenterUser, TestCenterUserForm, TestCenterRegistration, from student.models import (Registration, UserProfile, TestCenterUser, TestCenterUserForm,
TestCenterRegistration, TestCenterRegistrationForm,
PendingNameChange, PendingEmailChange, PendingNameChange, PendingEmailChange,
CourseEnrollment, unique_id_for_user, CourseEnrollment, unique_id_for_user,
get_testcenter_registrations_for_user_and_course) get_testcenter_registrations_for_user_and_course)
...@@ -248,8 +247,6 @@ def dashboard(request): ...@@ -248,8 +247,6 @@ def dashboard(request):
'show_courseware_links_for' : show_courseware_links_for, 'show_courseware_links_for' : show_courseware_links_for,
'cert_statuses': cert_statuses, 'cert_statuses': cert_statuses,
'news': top_news, 'news': top_news,
# No longer needed here...move to begin_registration
# 'testcenteruser': testcenteruser,
} }
return render_to_response('dashboard.html', context) return render_to_response('dashboard.html', context)
...@@ -657,11 +654,12 @@ def create_test_registration(request, post_override=None): ...@@ -657,11 +654,12 @@ def create_test_registration(request, post_override=None):
try: try:
testcenter_user = TestCenterUser.objects.get(user=user) testcenter_user = TestCenterUser.objects.get(user=user)
needs_updating = testcenter_user.needs_update(post_vars)
except TestCenterUser.DoesNotExist: except TestCenterUser.DoesNotExist:
# do additional initialization here: # do additional initialization here:
testcenter_user = TestCenterUser.create(user) testcenter_user = TestCenterUser.create(user)
needs_updating = True
needs_updating = testcenter_user.needs_update(post_vars)
# perform validation: # perform validation:
if needs_updating: if needs_updating:
...@@ -692,20 +690,28 @@ def create_test_registration(request, post_override=None): ...@@ -692,20 +690,28 @@ def create_test_registration(request, post_override=None):
# right now. # right now.
else: else:
accommodation_request = post_vars.get('accommodations','') accommodation_request = post_vars.get('accommodation_request','')
registration = TestCenterRegistration.create(testcenter_user, course_id, exam_info, accommodation_request) registration = TestCenterRegistration.create(testcenter_user, course_id, exam_info, accommodation_request)
needs_saving = True needs_saving = True
# TODO: add validation of registration. (Mainly whether an accommodation request is too long.)
if needs_saving: if needs_saving:
registration.save() # do validation of registration. (Mainly whether an accommodation request is too long.)
form = TestCenterRegistrationForm(instance=registration, data=post_vars)
if form.is_valid():
form.update_and_save()
else:
response_data = {'success': False}
# return a list of errors...
response_data['field_errors'] = form.errors
response_data['non_field_errors'] = form.non_field_errors()
return HttpResponse(json.dumps(response_data), mimetype="application/json")
# only do the following if there is accommodation text to send, # only do the following if there is accommodation text to send,
# and a destination to which to send it. # and a destination to which to send it.
# TODO: still need to create the accommodation email templates # TODO: still need to create the accommodation email templates
if 'accommodations' in post_vars and settings.MITX_FEATURES.get('ACCOMMODATION_EMAIL'): if 'accommodation_request' in post_vars and settings.MITX_FEATURES.get('ACCOMMODATION_EMAIL'):
d = {'accommodations': post_vars['accommodations'] } d = {'accommodation_request': post_vars['accommodation_request'] }
# composes accommodation email # composes accommodation email
subject = render_to_string('emails/accommodation_email_subject.txt', d) subject = render_to_string('emails/accommodation_email_subject.txt', d)
......
...@@ -247,7 +247,7 @@ ...@@ -247,7 +247,7 @@
<div class="message message-status is-shown exam-schedule"> <div class="message message-status is-shown exam-schedule">
<!-- TODO: pull Pearson destination out into a Setting --> <!-- TODO: pull Pearson destination out into a Setting -->
<a href="https://www1.pearsonvue.com/testtaker/signin/SignInPage/EDX" class="exam-button">Schedule Pearson exam</a> <a href="https://www1.pearsonvue.com/testtaker/signin/SignInPage/EDX" class="exam-button">Schedule Pearson exam</a>
<p class="exam-registration-number"><a href="${testcenter_register_target}" id="exam_register_link">Registration</a> number: <strong>edx00015879548</strong></p> <p class="exam-registration-number"><a href="${testcenter_register_target}" id="exam_register_link">Registration</a> number: <strong>${registrations[0].client_authorization_id}</strong></p>
<p class="message-copy">Write this down! You’ll need it to schedule your exam.</p> <p class="message-copy">Write this down! You’ll need it to schedule your exam.</p>
</div> </div>
% endif % endif
......
...@@ -68,17 +68,6 @@ ...@@ -68,17 +68,6 @@
$("label").removeClass("is-focused"); $("label").removeClass("is-focused");
}); });
$(document).delegate('#testcenter_register_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
location.href="${reverse('dashboard')}";
} else {
if($('#testcenter_register_error').length == 0) {
$('#testcenter_register_form').prepend('<div id="testcenter_register_error" class="modal-form-error"></div>');
}
$('#testcenter_register_error').text(json.field_errors).stop().css("display", "block");
}
});
})(this) })(this)
</script> </script>
</%block> </%block>
...@@ -262,9 +251,9 @@ ...@@ -262,9 +251,9 @@
</li> </li>
% endif % endif
% else: % else:
<li class="field"> <li data-field="accommodation_request" class="field">
<label for="accommodations">Accommodations Requested</label> <label for="accommodations">Accommodations Requested</label>
<textarea class="long" id="accommodations" name="accommodations" value="" placeholder=""></textarea> <textarea class="long" id="accommodations" name="accommodation_request" value="" placeholder=""></textarea>
</li> </li>
% endif % endif
</ol> </ol>
...@@ -290,7 +279,7 @@ ...@@ -290,7 +279,7 @@
<% regstatus = "Registration approved by Pearson" %> <% regstatus = "Registration approved by Pearson" %>
<div class="message message-status registration-accepted is-shown"> <div class="message message-status registration-accepted is-shown">
<p class="registration-status"><span class="label">Registration Status: </span><span class="value">${regstatus}</span></p> <p class="registration-status"><span class="label">Registration Status: </span><span class="value">${regstatus}</span></p>
<p class="registration-number"><span class="label">Registration number: </span> <span class="value">edx00015879548</span></p> <p class="registration-number"><span class="label">Registration number: </span> <span class="value">${registration.client_authorization_id}</span></p>
<p class="message-copy">Write this down! You’ll need it to schedule your exam.</p> <p class="message-copy">Write this down! You’ll need it to schedule your exam.</p>
<a href="https://www1.pearsonvue.com/testtaker/signin/SignInPage/EDX" class="button exam-button">Schedule Pearson exam</a> <a href="https://www1.pearsonvue.com/testtaker/signin/SignInPage/EDX" class="button exam-button">Schedule Pearson exam</a>
</div> </div>
......
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