Commit c5cc15a9 by Brian Wilson

return json, and add validation errors. Start displaying field with error.

parent c76f3705
...@@ -217,20 +217,26 @@ class TestCenterUser(models.Model): ...@@ -217,20 +217,26 @@ class TestCenterUser(models.Model):
return False return False
def update(self, dict): # def update(self, dict):
# leave user and client_candidate_id as before # # leave user and client_candidate_id as before
self.user_updated_at = datetime.now() # self.user_updated_at = datetime.now()
for fieldname in TestCenterUser.user_provided_fields(): # for fieldname in TestCenterUser.user_provided_fields():
self.__setattr__(fieldname, dict[fieldname]) # self.__setattr__(fieldname, dict[fieldname])
# @staticmethod
# def create(user, dict):
# testcenter_user = TestCenterUser(user=user)
# testcenter_user.update(dict)
# # testcenter_user.candidate_id remains unset
# # TODO: assign an ID of our own:
# testcenter_user.client_candidate_id = 'edx' + unique_id_for_user(user) # some unique value
@staticmethod @staticmethod
def create(user, dict): def create(user):
testcenter_user = TestCenterUser(user=user) testcenter_user = TestCenterUser(user=user)
testcenter_user.update(dict)
# testcenter_user.candidate_id remains unset # testcenter_user.candidate_id remains unset
# TODO: assign an ID of our own: # assign an ID of our own:
testcenter_user.client_candidate_id = 'edx' + '123456' # some unique value testcenter_user.client_candidate_id = 'edx' + unique_id_for_user(user) # some unique value
class TestCenterUserForm(ModelForm): class TestCenterUserForm(ModelForm):
class Meta: class Meta:
...@@ -239,8 +245,11 @@ class TestCenterUserForm(ModelForm): ...@@ -239,8 +245,11 @@ class TestCenterUserForm(ModelForm):
'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country', 'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country',
'phone', 'extension', 'phone_country_code', 'fax', 'fax_country_code', 'company_name') 'phone', 'extension', 'phone_country_code', 'fax', 'fax_country_code', 'company_name')
def update_and_save(self):
new_user = self.save(commit=False)
# create additional values here:
new_user.user_updated_at = datetime.now()
new_user.save()
...@@ -286,7 +295,7 @@ class TestCenterRegistration(models.Model): ...@@ -286,7 +295,7 @@ class TestCenterRegistration(models.Model):
user_updated_at = models.DateTimeField(db_index=True) user_updated_at = models.DateTimeField(db_index=True)
# "client_authorization_id" is the client's unique identifier for the authorization. # "client_authorization_id" is the client's unique identifier for the authorization.
# This must be present for an update or delete to be sent to Pearson. # This must be present for an update or delete to be sent to Pearson.
# client_authorization_id = models.CharField(max_length=20, unique=True, db_index=True) #client_authorization_id = models.CharField(max_length=20, unique=True, db_index=True)
# information about the test, from the course policy: # information about the test, from the course policy:
exam_series_code = models.CharField(max_length=15, db_index=True) exam_series_code = models.CharField(max_length=15, db_index=True)
...@@ -312,24 +321,50 @@ class TestCenterRegistration(models.Model): ...@@ -312,24 +321,50 @@ class TestCenterRegistration(models.Model):
def client_candidate_id(self): def client_candidate_id(self):
return self.testcenter_user.client_candidate_id return self.testcenter_user.client_candidate_id
@property @staticmethod
def client_authorization_id(self): def create(testcenter_user, course_id, exam_info, accommodation_request):
# TODO: make this explicitly into a string object: registration = TestCenterRegistration(testcenter_user = testcenter_user)
return self.id registration.course_id = course_id
registration.accommodation_request = accommodation_request
def get_testcenter_registrations_for_user_and_course(user, course_id): registration.exam_series_code = exam_info.get('Exam_Series_Code')
registration.eligibility_appointment_date_first = exam_info.get('First_Eligible_Appointment_Date')
registration.eligibility_appointment_date_last = exam_info.get('Last_Eligible_Appointment_Date')
# accommodation_code remains blank for now, along with Pearson confirmation
registration.user_updated_at = datetime.now()
#registration.client_authorization_id = registration._create_client_authorization_id()
return registration
def _create_client_authorization_id(self):
"""
Return a unique id for a registration, suitable for inserting into
e.g. personalized survey links.
"""
# include the secret key as a salt, and to make the ids unique across
# different LMS installs. Then add in (user, course, exam), which should
# be unique.
h = hashlib.md5()
h.update(settings.SECRET_KEY)
h.update(str(self.testcenter_user.user.id))
h.update(str(self.course_id))
h.update(str(self.exam_series_code))
return h.hexdigest()
def get_testcenter_registrations_for_user_and_course(user, course_id, exam_series_code=None):
try: try:
tcu = TestCenterUser.objects.get(user=user) tcu = TestCenterUser.objects.get(user=user)
except TestCenterUser.DoesNotExist: except TestCenterUser.DoesNotExist:
return [] return []
return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id) if exam_series_code is None:
return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id)
else:
return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id, exam_series_code=exam_series_code)
def unique_id_for_user(user): def unique_id_for_user(user):
""" """
Return a unique id for a user, suitable for inserting into Return a unique id for a user, suitable for inserting into
e.g. personalized survey links. e.g. personalized survey links.
""" """
# include the secret key as a salt, and to make the ids unique accross # include the secret key as a salt, and to make the ids unique across
# different LMS installs. # different LMS installs.
h = hashlib.md5() h = hashlib.md5()
h.update(settings.SECRET_KEY) h.update(settings.SECRET_KEY)
......
...@@ -614,6 +614,8 @@ def begin_test_registration(request, course_id, form=None, message=''): ...@@ -614,6 +614,8 @@ def begin_test_registration(request, course_id, form=None, message=''):
registration = registrations[0] registration = registrations[0]
else: else:
registration = None registration = None
log.info("User {0} enrolled in course {1} calls for test registration page".format(user.username, course_id))
# we want to populate the registration page with the relevant information, # we want to populate the registration page with the relevant information,
# if it already exists. Create an empty object otherwise. # if it already exists. Create an empty object otherwise.
...@@ -654,44 +656,31 @@ def create_test_registration(request, post_override=None): ...@@ -654,44 +656,31 @@ def create_test_registration(request, post_override=None):
user = User.objects.get(username=username) user = User.objects.get(username=username)
course_id = post_vars['course_id'] course_id = post_vars['course_id']
course = (course_from_id(course_id)) # assume it will be found.... course = (course_from_id(course_id)) # assume it will be found....
log.info("User {0} enrolled in course {1} clicked on enter/update demographic info for test registration".format(user.username, course_id))
# needs_saving = False
try: try:
testcenter_user = TestCenterUser.objects.get(user=user) testcenter_user = TestCenterUser.objects.get(user=user)
except TestCenterUser.DoesNotExist: except TestCenterUser.DoesNotExist:
testcenter_user = TestCenterUser(user=user) # do additional initialization here:
testcenter_user = TestCenterUser.create(user)
needs_updating = testcenter_user.needs_update(post_vars) needs_updating = testcenter_user.needs_update(post_vars)
# if needs_updating:
# testcenter_user.update(post_vars)
# needs_saving = True
# except TestCenterUser.DoesNotExist:
# did not find the TestCenterUser, so create a new one
# testcenter_user = TestCenterUser.create(user, post_vars)
# needs_saving = True
# perform validation: # perform validation:
if needs_updating: if needs_updating:
log.info("User {0} enrolled in course {1} updating demographic info for test registration".format(user.username, course_id))
try: try:
# first perform validation on the user information # first perform validation on the user information
# using a Django Form. # using a Django Form.
form = TestCenterUserForm(instance=testcenter_user, data=post_vars) form = TestCenterUserForm(instance=testcenter_user, data=post_vars)
if not form.is_valid(): if not form.is_valid():
return begin_test_registration(request, course_id, form, 'failed to validate') # return begin_test_registration(request, course_id, form, 'failed to validate')
# response_data = {'success': False} response_data = {'success': False}
# # return a list of errors... # return a list of errors...
# response_data['field_errors'] = form.errors response_data['field_errors'] = form.errors
# response_data['non_field_errors'] = form.non_field_errors() response_data['non_field_errors'] = form.non_field_errors()
# return HttpResponse(json.dumps(response_data)) return HttpResponse(json.dumps(response_data), mimetype="application/json")
form.update_and_save()
new_user = form.save(commit=False)
# create additional values here:
new_user.user_updated_at = datetime.datetime.now()
# TODO: create client value....
new_user.save()
# testcenter_user.save()
except IntegrityError, ie: except IntegrityError, ie:
js = {'success': False} js = {'success': False}
error_msg = unicode(ie); error_msg = unicode(ie);
...@@ -700,15 +689,16 @@ def create_test_registration(request, post_override=None): ...@@ -700,15 +689,16 @@ def create_test_registration(request, post_override=None):
if error_msg.find(fieldname) >= 0: if error_msg.find(fieldname) >= 0:
js['value'] = error_msg js['value'] = error_msg
js['field'] = fieldname js['field'] = fieldname
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js), mimetype="application/json")
# otherwise just return the error message # otherwise just return the error message
js['value'] = error_msg js['value'] = error_msg
js['field'] = "General Error" js['field'] = "General Error"
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js), mimetype="application/json")
# create and save the registration: # create and save the registration:
needs_saving = False needs_saving = False
registrations = get_testcenter_registrations_for_user_and_course(user, course.id) exam_info = course.testcenter_info
registrations = get_testcenter_registrations_for_user_and_course(user, course_id)
# In future, this should check the exam series code of the registrations, if there # In future, this should check the exam series code of the registrations, if there
# were multiple. # were multiple.
if len(registrations) > 0: if len(registrations) > 0:
...@@ -719,15 +709,8 @@ def create_test_registration(request, post_override=None): ...@@ -719,15 +709,8 @@ def create_test_registration(request, post_override=None):
# right now. # right now.
else: else:
registration = TestCenterRegistration(testcenter_user = testcenter_user) accommodation_request = post_vars.get('accommodations','')
registration.course_id = post_vars['course_id'] registration = TestCenterRegistration.create(testcenter_user, course_id, exam_info, accommodation_request)
registration.accommodation_request = post_vars.get('accommodations','')
exam_info = course.testcenter_info
registration.exam_series_code = exam_info.get('Exam_Series_Code')
registration.eligibility_appointment_date_first = exam_info.get('First_Eligible_Appointment_Date')
registration.eligibility_appointment_date_last = exam_info.get('Last_Eligible_Appointment_Date')
# accommodation_code remains blank for now, along with Pearson confirmation
registration.user_updated_at = datetime.datetime.now()
needs_saving = True needs_saving = True
# "client_authorization_id" is the client's unique identifier for the authorization. # "client_authorization_id" is the client's unique identifier for the authorization.
...@@ -790,14 +773,17 @@ def create_test_registration(request, post_override=None): ...@@ -790,14 +773,17 @@ def create_test_registration(request, post_override=None):
except: except:
log.exception(sys.exc_info()) log.exception(sys.exc_info())
js['value'] = 'Could not send accommodation e-mail.' js['value'] = 'Could not send accommodation e-mail.'
return HttpResponse(json.dumps(js)) return HttpResponse(json.dumps(js), mimetype="application/json")
# TODO: enable appropriate stat # TODO: enable appropriate stat
# statsd.increment("common.student.account_created") # statsd.increment("common.student.account_created")
# js = {'success': True} log.info("User {0} enrolled in course {1} returning from enter/update demographic info for test registration".format(user.username, course_id))
# return HttpResponse(json.dumps(js), mimetype="application/json")
return HttpResponseRedirect(reverse('dashboard')) js = {'success': True}
return HttpResponse(json.dumps(js), mimetype="application/json")
# return HttpResponseRedirect(reverse('dashboard'))
#return HttpResponse("Hello world")
def get_random_post_override(): def get_random_post_override():
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="title"><title>Pearson VUE Test Center Proctoring - Sign Up</title></%block> <%block name="title"><title>Pearson VUE Test Center Proctoring - Sign Up</title></%block>
<%doc>
<%block name="js_extra"> <%block name="js_extra">
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
...@@ -19,9 +19,20 @@ ...@@ -19,9 +19,20 @@
if(json.success) { if(json.success) {
location.href="${reverse('dashboard')}"; location.href="${reverse('dashboard')}";
} else { } else {
$(".field.error").removeClass('error'); var field_errors = json.field_errors;
var non_field_errors = json.non_field_errors;
var fieldname;
var field_errorlist;
var field_error;
$(".field.error").removeClass('error');
for (fieldname in field_errors) {
field_errorlist = field_errors[fieldname];
for (i=0; i < field_errorlist.length; i+= 1) {
field_error = field_errorlist[i];
}
$("[data-field='"+fieldname+"']").addClass('error')
}
$('#register_error').html(json.value).stop().css("display", "block"); $('#register_error').html(json.value).stop().css("display", "block");
$("[data-field='"+json.field+"']").addClass('error')
} }
}); });
...@@ -31,11 +42,20 @@ ...@@ -31,11 +42,20 @@
$("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>
</%doc>
<section class="testcenter-register container"> <section class="testcenter-register container">
...@@ -80,7 +100,7 @@ ...@@ -80,7 +100,7 @@
<header> <header>
<h3 class="is-hidden">Registration Form</h3> <h3 class="is-hidden">Registration Form</h3>
</header> </header>
<form id="testcenter-register-form" method="post" data-remote="true" action="/create_test_registration"> <form id="testcenter_register_form" method="post" data-remote="true" action="/create_test_registration">
% if registration: % if registration:
<p class="instructions"> <p class="instructions">
...@@ -103,11 +123,11 @@ ...@@ -103,11 +123,11 @@
<ol class="list-input"> <ol class="list-input">
<li class="field"> <li class="field">
<label for="id-salutation">Salutation:</label> <label for="id_salutation">Salutation:</label>
${form['salutation']} ${form['salutation']}
</li> </li>
<li class="field required"> <li class="field required">
<label for="id-first_name">First Name:</label> <label for="id_first_name">First Name:</label>
${form['first_name']} ${form['first_name']}
</li> </li>
<!-- <li class="field"> <!-- <li class="field">
...@@ -153,19 +173,19 @@ ...@@ -153,19 +173,19 @@
</div> </div>
</li> </li>
<li class="field-group postal"> <li class="field-group postal">
<div class="field"> <div data-field="city" class="field">
<label for="city">City</label> <label for="city">City</label>
<input id="city" class="short" type="text" name="city" value="${testcenteruser.city}" placeholder="e.g. Newark" /> <input id="city" class="short" type="text" name="city" value="${testcenteruser.city}" placeholder="e.g. Newark" />
</div> </div>
<div class="field"> <div data-field="state" class="field">
<label for="state">State/Province</label> <label for="state">State/Province</label>
<input id="state" class="short" type="text" name="state" value="${testcenteruser.state}" placeholder="e.g. NJ" /> <input id="state" class="short" type="text" name="state" value="${testcenteruser.state}" placeholder="e.g. NJ" />
</div> </div>
<div class="field"> <div data-field="postal_code" class="field">
<label for="postal-code">Postal Code</label> <label for="postal-code">Postal Code</label>
<input id="postal-code" class="short" type="text" name="postal_code" value="${testcenteruser.postal_code}" placeholder="e.g. 08540" /> <input id="postal-code" class="short" type="text" name="postal_code" value="${testcenteruser.postal_code}" placeholder="e.g. 08540" />
</div> </div>
<div class="field required"> <div data-field="country" class="field required">
<label class="short" for="country-code">Country Code</label> <label class="short" for="country-code">Country Code</label>
<input id="country-code" class="short" type="text" name="country" value="${testcenteruser.country}" placeholder="e.g. USA" /> <input id="country-code" class="short" type="text" name="country" value="${testcenteruser.country}" placeholder="e.g. USA" />
</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