add additional fields to testcenter user and update test center registration.
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
# -*- 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 '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.confirmed_at'
|
||||
db.add_column('student_testcenteruser', 'confirmed_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'
|
||||
db.create_table('student_testcenterregistration', (
|
||||
('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)),
|
||||
('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)),
|
||||
('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)),
|
||||
('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)),
|
||||
('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)),
|
||||
('accommodation_code', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
|
||||
('accommodation_request', self.gf('django.db.models.fields.CharField')(max_length=1024, blank=True)),
|
||||
('upload_status', self.gf('django.db.models.fields.CharField')(max_length=20, blank=True)),
|
||||
('confirmed_at', self.gf('django.db.models.fields.DateTimeField')(db_index=True)),
|
||||
('upload_error_message', self.gf('django.db.models.fields.CharField')(max_length=512, blank=True)),
|
||||
))
|
||||
db.send_create_signal('student', ['TestCenterRegistration'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'TestCenterRegistration'
|
||||
db.delete_table('student_testcenterregistration')
|
||||
|
||||
# Deleting field 'TestCenterUser.upload_status'
|
||||
db.delete_column('student_testcenteruser', 'upload_status')
|
||||
|
||||
# Deleting field 'TestCenterUser.confirmed_at'
|
||||
db.delete_column('student_testcenteruser', 'confirmed_at')
|
||||
|
||||
# Deleting field 'TestCenterUser.upload_error_message'
|
||||
db.delete_column('student_testcenteruser', 'upload_error_message')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'student.courseenrollment': {
|
||||
'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'CourseEnrollment'},
|
||||
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'student.pendingemailchange': {
|
||||
'Meta': {'object_name': 'PendingEmailChange'},
|
||||
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'new_email': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
},
|
||||
'student.pendingnamechange': {
|
||||
'Meta': {'object_name': 'PendingNameChange'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'new_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'rationale': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
},
|
||||
'student.registration': {
|
||||
'Meta': {'object_name': 'Registration', 'db_table': "'auth_registration'"},
|
||||
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'db_index': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
},
|
||||
'student.testcenterregistration': {
|
||||
'Meta': {'object_name': 'TestCenterRegistration'},
|
||||
'accommodation_code': ('django.db.models.fields.CharField', [], {'max_length': '64', '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'}),
|
||||
'confirmed_at': ('django.db.models.fields.DateTimeField', [], {'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'}),
|
||||
'eligibility_appointment_date_first': ('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'}),
|
||||
'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'}),
|
||||
'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_status': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
|
||||
'user_updated_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'})
|
||||
},
|
||||
'student.testcenteruser': {
|
||||
'Meta': {'object_name': 'TestCenterUser'},
|
||||
'address_1': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'address_2': ('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'}),
|
||||
'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'}),
|
||||
'company_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'confirmed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', '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'}),
|
||||
'extension': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '8', 'blank': 'True'}),
|
||||
'fax': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}),
|
||||
'fax_country_code': ('django.db.models.fields.CharField', [], {'max_length': '3', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'db_index': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||
'middle_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'phone': ('django.db.models.fields.CharField', [], {'max_length': '35'}),
|
||||
'phone_country_code': ('django.db.models.fields.CharField', [], {'max_length': '3', 'db_index': 'True'}),
|
||||
'postal_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}),
|
||||
'salutation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
|
||||
'state': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '20', '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'}),
|
||||
'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'}),
|
||||
'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'})
|
||||
},
|
||||
'student.userprofile': {
|
||||
'Meta': {'object_name': 'UserProfile', 'db_table': "'auth_userprofile'"},
|
||||
'courseware': ('django.db.models.fields.CharField', [], {'default': "'course.xml'", 'max_length': '255', 'blank': 'True'}),
|
||||
'gender': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
|
||||
'goals': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
|
||||
'level_of_education': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '6', 'null': 'True', 'blank': 'True'}),
|
||||
'location': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
|
||||
'mailing_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'meta': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
|
||||
'year_of_birth': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'student.usertestgroup': {
|
||||
'Meta': {'object_name': 'UserTestGroup'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['student']
|
||||
@@ -141,6 +141,9 @@ class TestCenterUser(models.Model):
|
||||
The field names and lengths are modeled on the conventions and constraints
|
||||
of Pearson's data import system, including oddities such as suffix having
|
||||
a limit of 255 while last_name only gets 50.
|
||||
|
||||
Also storing here the confirmation information received from Pearson (if any)
|
||||
as to the success or failure of the upload. (VCDC file)
|
||||
"""
|
||||
# Our own record keeping...
|
||||
user = models.ForeignKey(User, unique=True, default=None)
|
||||
@@ -155,7 +158,7 @@ class TestCenterUser(models.Model):
|
||||
# we first create the User entry, and is assigned by Pearson later.
|
||||
candidate_id = models.IntegerField(null=True, db_index=True)
|
||||
|
||||
# Unique ID we assign our user for a the Test Center.
|
||||
# Unique ID we assign our user for the Test Center.
|
||||
client_candidate_id = models.CharField(max_length=50, db_index=True)
|
||||
|
||||
# Name
|
||||
@@ -189,6 +192,11 @@ class TestCenterUser(models.Model):
|
||||
# Company
|
||||
company_name = models.CharField(max_length=50, blank=True)
|
||||
|
||||
# Confirmation
|
||||
upload_status = models.CharField(max_length=20, blank=True) # 'Error' or 'Accepted'
|
||||
confirmed_at = models.DateTimeField(null=True, db_index=True)
|
||||
upload_error_message = models.CharField(max_length=512, blank=True)
|
||||
|
||||
@staticmethod
|
||||
def user_provided_fields():
|
||||
return [ 'first_name', 'middle_name', 'last_name', 'suffix', 'salutation',
|
||||
@@ -212,17 +220,38 @@ class TestCenterRegistration(models.Model):
|
||||
The field names and lengths are modeled on the conventions and constraints
|
||||
of Pearson's data import system.
|
||||
"""
|
||||
# TODO: Check the spec to find out lengths specified by Pearson
|
||||
|
||||
# to find an exam registration, we key off of the user and course_id.
|
||||
# If multiple exams per course are possible, we would also need to add the
|
||||
# exam_series_code.
|
||||
testcenter_user = models.ForeignKey(TestCenterUser, unique=True, default=None)
|
||||
course_id = models.CharField(max_length=128, db_index=True)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||
updated_at = models.DateTimeField(auto_now=True, db_index=True)
|
||||
course_id = models.CharField(max_length=128, db_index=True)
|
||||
# user_updated_at happens only when the user makes a change to their data,
|
||||
# and is something Pearson needs to know to manage updates. Unlike
|
||||
# updated_at, this will not get incremented when we do a batch data import.
|
||||
# The appointment dates, the exam count, and the accommodation codes can be updated,
|
||||
# but hopefully this won't happen often.
|
||||
user_updated_at = models.DateTimeField(db_index=True)
|
||||
# "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.
|
||||
client_authorization_id = models.CharField(max_length=20, unique=True, db_index=True)
|
||||
|
||||
# information about the test, from the course policy:
|
||||
exam_series_code = models.CharField(max_length=15, db_index=True)
|
||||
eligibility_appointment_date_first = models.DateField(db_index=True)
|
||||
eligibility_appointment_date_last = models.DateField(db_index=True)
|
||||
# TODO: this should be an enumeration:
|
||||
accommodation_code = models.CharField(max_length=64, blank=True)
|
||||
|
||||
# store the original text of the accommodation request.
|
||||
accommodation_request = models.CharField(max_length=1024, blank=True)
|
||||
# TODO: this should be an enumeration:
|
||||
accommodation_code = models.CharField(max_length=64, blank=True)
|
||||
|
||||
# Confirmation
|
||||
upload_status = models.CharField(max_length=20, blank=True) # 'Error' or 'Accepted'
|
||||
confirmed_at = models.DateTimeField(db_index=True)
|
||||
upload_error_message = models.CharField(max_length=512, blank=True)
|
||||
|
||||
@property
|
||||
def candidate_id(self):
|
||||
@@ -232,6 +261,15 @@ class TestCenterRegistration(models.Model):
|
||||
def client_candidate_id(self):
|
||||
return self.testcenter_user.client_candidate_id
|
||||
|
||||
|
||||
|
||||
def get_testcenter_registrations_for_user_and_course(user, course_id):
|
||||
try:
|
||||
tcu = TestCenterUser.objects.get(user=user)
|
||||
except User.DoesNotExist:
|
||||
return []
|
||||
return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id)
|
||||
|
||||
def unique_id_for_user(user):
|
||||
"""
|
||||
Return a unique id for a user, suitable for inserting into
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import datetime
|
||||
import feedparser
|
||||
import itertools
|
||||
#import itertools
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
#import time
|
||||
import urllib
|
||||
import uuid
|
||||
|
||||
@@ -19,7 +19,8 @@ from django.core.context_processors import csrf
|
||||
from django.core.mail import send_mail
|
||||
from django.core.validators import validate_email, validate_slug, ValidationError
|
||||
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 mitxmako.shortcuts import render_to_response, render_to_string
|
||||
from bs4 import BeautifulSoup
|
||||
@@ -37,13 +38,14 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
|
||||
from datetime import date
|
||||
#from datetime import date
|
||||
from collections import namedtuple
|
||||
|
||||
from courseware.courses import get_courses_by_university
|
||||
from courseware.access import has_access
|
||||
|
||||
from statsd import statsd
|
||||
from django.contrib.localflavor.ie.ie_counties import IE_COUNTY_CHOICES
|
||||
|
||||
log = logging.getLogger("mitx.student")
|
||||
Article = namedtuple('Article', 'title url author image deck publication publish_date')
|
||||
@@ -640,9 +642,11 @@ def _do_create_or_update_test_center_user(post_vars):
|
||||
|
||||
# first determine if we need to create a new TestCenterUser, or if we are making any update
|
||||
# to an existing TestCenterUser.
|
||||
username=post_vars['username']
|
||||
username = post_vars['username']
|
||||
user = User.objects.get(username=username)
|
||||
|
||||
course_id = post_vars['course_id']
|
||||
course = (course_from_id(course_id)) # assume it will be found....
|
||||
|
||||
needs_saving = False
|
||||
try:
|
||||
testcenter_user = TestCenterUser.objects.get(user=user)
|
||||
@@ -651,9 +655,8 @@ def _do_create_or_update_test_center_user(post_vars):
|
||||
for fieldname in TestCenterUser.user_provided_fields()])
|
||||
|
||||
if needs_updating:
|
||||
# TODO: what do we set a timestamp to, in order to get now()?
|
||||
# leave user and client_candidate_id as before
|
||||
testcenter_user.user_updated_at = datetime.datetime.now()
|
||||
# Now do the update:
|
||||
for fieldname in TestCenterUser.user_provided_fields():
|
||||
testcenter_user.__setattr__(fieldname, post_vars[fieldname])
|
||||
needs_saving = True
|
||||
@@ -661,7 +664,6 @@ def _do_create_or_update_test_center_user(post_vars):
|
||||
except TestCenterUser.DoesNotExist:
|
||||
# did not find the TestCenterUser, so create a new one
|
||||
testcenter_user = TestCenterUser(user=user)
|
||||
# testcenter_user.user = user
|
||||
for fieldname in TestCenterUser.user_provided_fields():
|
||||
testcenter_user.__setattr__(fieldname, post_vars[fieldname])
|
||||
# testcenter_user.candidate_id remains unset
|
||||
@@ -670,31 +672,43 @@ def _do_create_or_update_test_center_user(post_vars):
|
||||
needs_saving = True
|
||||
|
||||
# additional validation occurs at save time, so handle exceptions
|
||||
# TODO: Rearrange so that if part of the process fails, the whole process fails.
|
||||
# Right now, we can have e.g. no registration e-mail sent out and a zombie account
|
||||
if needs_saving:
|
||||
try:
|
||||
testcenter_user.save()
|
||||
except IntegrityError:
|
||||
js = {'success': False}
|
||||
# TODO: Figure out the cause of the integrity error
|
||||
if len(User.objects.filter(username=post_vars['username'])) > 0:
|
||||
js['value'] = "An account with this username already exists."
|
||||
js['field'] = 'username'
|
||||
return HttpResponse(json.dumps(js))
|
||||
except IntegrityError, ie:
|
||||
message = ie
|
||||
context = {'course': course,
|
||||
'user': user,
|
||||
'message': message,
|
||||
'testcenteruser': testcenter_user,
|
||||
}
|
||||
return render_to_response('test_center_register.html', context)
|
||||
|
||||
if len(User.objects.filter(email=post_vars['email'])) > 0:
|
||||
js['value'] = "An account with this e-mail already exists."
|
||||
js['field'] = 'email'
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
raise
|
||||
|
||||
|
||||
# create and save the registration:
|
||||
registration = TestCenterRegistration(testcenter_user = testcenter_user)
|
||||
# registration.register(user)
|
||||
registration.course_id = post_vars['course_id']
|
||||
registration.accommodation_request = post_vars['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()
|
||||
|
||||
# "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.
|
||||
registration.client_authorization_id = "1"
|
||||
try:
|
||||
registration.save()
|
||||
except IntegrityError, ie:
|
||||
message = ie
|
||||
context = {'course': course,
|
||||
'user': user,
|
||||
'message': message,
|
||||
'testcenteruser': testcenter_user,
|
||||
}
|
||||
return render_to_response('test_center_register.html', context)
|
||||
|
||||
|
||||
return (user, testcenter_user, registration)
|
||||
|
||||
@@ -759,11 +773,12 @@ def create_test_registration(request, post_override=None):
|
||||
js['value'] = 'Could not send accommodation e-mail.'
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
|
||||
# TODO: enable appropriate stat
|
||||
# statsd.increment("common.student.account_created")
|
||||
|
||||
js = {'success': True}
|
||||
return HttpResponse(json.dumps(js), mimetype="application/json")
|
||||
# js = {'success': True}
|
||||
# return HttpResponse(json.dumps(js), mimetype="application/json")
|
||||
return HttpResponseRedirect('/dashboard')
|
||||
|
||||
def get_random_post_override():
|
||||
"""
|
||||
|
||||
@@ -315,7 +315,7 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
Returns None if no url specified.
|
||||
"""
|
||||
return self.metadata.get('end_of_course_survey_url')
|
||||
|
||||
|
||||
@property
|
||||
def testcenter_info(self):
|
||||
"""
|
||||
@@ -324,10 +324,17 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
TODO: decide if we expect this entry to be a single test, or if multiple tests are possible
|
||||
per course.
|
||||
|
||||
Returns None if no testcenter info specified.
|
||||
For now we expect this entry to be a single test.
|
||||
|
||||
Returns None if no testcenter info specified, or if no exam is included.
|
||||
"""
|
||||
return self.metadata.get('testcenter_info')
|
||||
|
||||
info = self.metadata.get('testcenter_info')
|
||||
if info is None or len(info) == 0:
|
||||
return None;
|
||||
else:
|
||||
return info.values()[0]
|
||||
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self.display_name
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from courseware.courses import course_image_url, get_course_about_section
|
||||
from courseware.access import has_access
|
||||
from certificates.models import CertificateStatuses
|
||||
from student.models import get_testcenter_registrations_for_user_and_course
|
||||
%>
|
||||
<%inherit file="main.html" />
|
||||
|
||||
@@ -222,20 +223,26 @@
|
||||
<!-- TODO: need to add logic to select which of the following to display. Like certs? -->
|
||||
<%
|
||||
testcenter_info = course.testcenter_info
|
||||
testcenter_register_target = reverse('begin_test_registration', args=[course.id])
|
||||
%>
|
||||
% if testcenter_info is not None:
|
||||
|
||||
<%
|
||||
testcenter_register_target = reverse('begin_test_registration', args=[course.id])
|
||||
%>
|
||||
|
||||
<!-- see if there is already a registration object
|
||||
TODO: need to add logic for when registration can begin. -->
|
||||
<%
|
||||
registrations = get_testcenter_registrations_for_user_and_course(user, course.id)
|
||||
%>
|
||||
% if len(registrations) == 0:
|
||||
<div class="message message-status is-shown exam-register">
|
||||
<!-- <a href="#testcenter-register-modal" rel="leanModal" class="exam-button" data-course-id="${course.id}" data-course-number="${course.number}" id="exam_register_button">Register for Pearson exam</a>
|
||||
--> <a href="${testcenter_register_target}" class="exam-button" id="exam_register_button">Register for Pearson exam</a>
|
||||
<p class="message-copy">Registration for the Pearson exam is now open.</p>
|
||||
</div>
|
||||
|
||||
% else:
|
||||
<div class="message message-status is-shown">
|
||||
<p class="message-copy">Your registration for the Pearson exam is pending. Within a few days, you should receive a confirmation number, which can be used to schedule your exam.</p>
|
||||
<p class="message-copy">Your
|
||||
<a href="${testcenter_register_target}" id="exam_register_link">registration for the Pearson exam</a>
|
||||
is pending. Within a few days, you should see a confirmation number here, which can be used to schedule your exam.</p>
|
||||
</div>
|
||||
|
||||
<div class="message message-status is-shown exam-schedule">
|
||||
@@ -244,6 +251,7 @@
|
||||
<p class="exam-registration-number">Registration number: <strong>edx00015879548</strong></p>
|
||||
<p class="message-copy">Write this down! You’ll need it to schedule your exam.</p>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
% endif
|
||||
|
||||
|
||||
@@ -71,12 +71,9 @@
|
||||
|
||||
<!-- TODO: need to add logic to select which of the following to display. Like certs? -->
|
||||
<%
|
||||
testcenter_info = course.testcenter_info
|
||||
exam_info = course.testcenter_info
|
||||
%>
|
||||
% if testcenter_info is not None:
|
||||
<%
|
||||
exam_info = testcenter_info.get('Final_Exam')
|
||||
%>
|
||||
% if exam_info is not None:
|
||||
<p>Exam Series Code: ${exam_info.get('Exam_Series_Code')}</p>
|
||||
<p>First Eligible Appointment Date: ${exam_info.get('First_Eligible_Appointment_Date')}</p>
|
||||
<p>Last Eligible Appointment Date: ${exam_info.get('Last_Eligible_Appointment_Date')}</p>
|
||||
|
||||
Reference in New Issue
Block a user