Commit 76c47305 by Victor Shnayder

whitespace

parent 66934ce2
......@@ -121,8 +121,8 @@ 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)
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...
......@@ -172,7 +172,7 @@ class TestCenterUser(models.Model):
uploaded_at = models.DateTimeField(null=True, blank=True, db_index=True)
# confirmation back from the test center, as well as timestamps
# on when they processed the request, and when we received
# on when they processed the request, and when we received
# confirmation back.
processed_at = models.DateTimeField(null=True, db_index=True)
upload_status = models.CharField(max_length=20, blank=True, db_index=True) # 'Error' or 'Accepted'
......@@ -186,52 +186,52 @@ class TestCenterUser(models.Model):
@property
def needs_uploading(self):
return self.uploaded_at is None or self.uploaded_at < self.user_updated_at
@staticmethod
def user_provided_fields():
return [ 'first_name', 'middle_name', 'last_name', 'suffix', 'salutation',
'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country',
return [ 'first_name', 'middle_name', 'last_name', 'suffix', 'salutation',
'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country',
'phone', 'extension', 'phone_country_code', 'fax', 'fax_country_code', 'company_name']
@property
def email(self):
return self.user.email
def needs_update(self, fields):
for fieldname in TestCenterUser.user_provided_fields():
if fieldname in fields and getattr(self, fieldname) != fields[fieldname]:
return True
return False
return False
@staticmethod
def _generate_edx_id(prefix):
NUM_DIGITS = 12
return u"{}{:012}".format(prefix, randint(1, 10**NUM_DIGITS-1))
@staticmethod
def _generate_candidate_id():
return TestCenterUser._generate_edx_id("edX")
@classmethod
def create(cls, user):
testcenter_user = cls(user=user)
# testcenter_user.candidate_id remains unset
# testcenter_user.candidate_id remains unset
# assign an ID of our own:
cand_id = cls._generate_candidate_id()
while TestCenterUser.objects.filter(client_candidate_id=cand_id).exists():
cand_id = cls._generate_candidate_id()
testcenter_user.client_candidate_id = cand_id
testcenter_user.client_candidate_id = cand_id
return testcenter_user
@property
def is_accepted(self):
return self.upload_status == TEST_CENTER_STATUS_ACCEPTED
@property
def is_rejected(self):
return self.upload_status == TEST_CENTER_STATUS_ERROR
@property
def is_pending(self):
return not self.is_accepted and not self.is_rejected
......@@ -239,26 +239,26 @@ class TestCenterUser(models.Model):
class TestCenterUserForm(ModelForm):
class Meta:
model = TestCenterUser
fields = ( 'first_name', 'middle_name', 'last_name', 'suffix', 'salutation',
'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country',
fields = ( 'first_name', 'middle_name', 'last_name', 'suffix', 'salutation',
'address_1', 'address_2', 'address_3', 'city', 'state', 'postal_code', 'country',
'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.utcnow()
new_user.upload_status = ''
new_user.save()
log.info("Updated demographic information for user's test center exam registration: username \"{}\" ".format(new_user.user.username))
log.info("Updated demographic information for user's test center exam registration: username \"{}\" ".format(new_user.user.username))
# add validation:
def clean_country(self):
code = self.cleaned_data['country']
if code and len(code) != 3:
raise forms.ValidationError(u'Must be three characters (ISO 3166-1): e.g. USA, CAN, MNG')
return code
def clean(self):
def _can_encode_as_latin(fieldvalue):
try:
......@@ -266,40 +266,40 @@ class TestCenterUserForm(ModelForm):
except UnicodeEncodeError:
return False
return True
cleaned_data = super(TestCenterUserForm, self).clean()
# check for interactions between fields:
if 'country' in cleaned_data:
country = cleaned_data.get('country')
if country == 'USA' or country == 'CAN':
if 'state' in cleaned_data and len(cleaned_data['state']) == 0:
self._errors['state'] = self.error_class([u'Required if country is USA or CAN.'])
self._errors['state'] = self.error_class([u'Required if country is USA or CAN.'])
del cleaned_data['state']
if 'postal_code' in cleaned_data and len(cleaned_data['postal_code']) == 0:
self._errors['postal_code'] = self.error_class([u'Required if country is USA or CAN.'])
self._errors['postal_code'] = self.error_class([u'Required if country is USA or CAN.'])
del cleaned_data['postal_code']
if 'fax' in cleaned_data and len(cleaned_data['fax']) > 0 and 'fax_country_code' in cleaned_data and len(cleaned_data['fax_country_code']) == 0:
self._errors['fax_country_code'] = self.error_class([u'Required if fax is specified.'])
self._errors['fax_country_code'] = self.error_class([u'Required if fax is specified.'])
del cleaned_data['fax_country_code']
# check encoding for all fields:
cleaned_data_fields = [fieldname for fieldname in cleaned_data]
for fieldname in cleaned_data_fields:
if not _can_encode_as_latin(cleaned_data[fieldname]):
self._errors[fieldname] = self.error_class([u'Must only use characters in Latin-1 (iso-8859-1) encoding'])
self._errors[fieldname] = self.error_class([u'Must only use characters in Latin-1 (iso-8859-1) encoding'])
del cleaned_data[fieldname]
# Always return the full collection of cleaned data.
return cleaned_data
# our own code to indicate that a request has been rejected.
ACCOMMODATION_REJECTED_CODE = 'NONE'
# our own code to indicate that a request has been rejected.
ACCOMMODATION_REJECTED_CODE = 'NONE'
ACCOMMODATION_CODES = (
(ACCOMMODATION_REJECTED_CODE, 'No Accommodation Granted'),
(ACCOMMODATION_REJECTED_CODE, 'No Accommodation Granted'),
('EQPMNT', 'Equipment'),
('ET12ET', 'Extra Time - 1/2 Exam Time'),
('ET30MN', 'Extra Time - 30 Minutes'),
......@@ -309,11 +309,11 @@ ACCOMMODATION_CODES = (
('SRRERC', 'Separate Room and Reader/Recorder'),
('SRRECR', 'Separate Room and Recorder'),
('SRSEAN', 'Separate Room and Service Animal'),
('SRSGNR', 'Separate Room and Sign Language Interpreter'),
('SRSGNR', 'Separate Room and Sign Language Interpreter'),
)
ACCOMMODATION_CODE_DICT = { code : name for (code, name) in ACCOMMODATION_CODES }
class TestCenterRegistration(models.Model):
"""
This is our representation of a user's registration for in-person testing,
......@@ -328,20 +328,20 @@ class TestCenterRegistration(models.Model):
of Pearson's data import system.
"""
# 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
# If multiple exams per course are possible, we would also need to add the
# exam_series_code.
testcenter_user = models.ForeignKey(TestCenterUser, 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)
# 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,
# 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 our unique identifier for the authorization.
# "client_authorization_id" is our 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)
......@@ -351,10 +351,10 @@ class TestCenterRegistration(models.Model):
eligibility_appointment_date_last = models.DateField(db_index=True)
# this is really a list of codes, using an '*' as a delimiter.
# So it's not a choice list. We use the special value of ACCOMMODATION_REJECTED_CODE
# So it's not a choice list. We use the special value of ACCOMMODATION_REJECTED_CODE
# to indicate the rejection of an accommodation request.
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, db_index=True)
......@@ -362,7 +362,7 @@ class TestCenterRegistration(models.Model):
uploaded_at = models.DateTimeField(null=True, db_index=True)
# confirmation back from the test center, as well as timestamps
# on when they processed the request, and when we received
# on when they processed the request, and when we received
# confirmation back.
processed_at = models.DateTimeField(null=True, db_index=True)
upload_status = models.CharField(max_length=20, blank=True, db_index=True) # 'Error' or 'Accepted'
......@@ -372,11 +372,11 @@ class TestCenterRegistration(models.Model):
# (However, it may never be set if we are always initiating such candidate creation.)
authorization_id = models.IntegerField(null=True, db_index=True)
confirmed_at = models.DateTimeField(null=True, db_index=True)
@property
def candidate_id(self):
return self.testcenter_user.candidate_id
@property
def client_candidate_id(self):
return self.testcenter_user.client_candidate_id
......@@ -389,20 +389,20 @@ class TestCenterRegistration(models.Model):
return 'Add'
else:
# TODO: decide what to send when we have uploaded an initial version,
# but have not received confirmation back from that upload. If the
# but have not received confirmation back from that upload. If the
# registration here has been changed, then we don't know if this changed
# registration should be submitted as an 'add' or an 'update'.
# registration should be submitted as an 'add' or an 'update'.
#
# If the first registration were lost or in error (e.g. bad code),
# If the first registration were lost or in error (e.g. bad code),
# the second should be an "Add". If the first were processed successfully,
# then the second should be an "Update". We just don't know....
return 'Update'
@property
def exam_authorization_count(self):
# TODO: figure out if this should really go in the database (with a default value).
return 1
@classmethod
def create(cls, testcenter_user, exam, accommodation_request):
registration = cls(testcenter_user = testcenter_user)
......@@ -418,7 +418,7 @@ class TestCenterRegistration(models.Model):
@staticmethod
def _generate_authorization_id():
return TestCenterUser._generate_edx_id("edXexam")
@staticmethod
def _create_client_authorization_id():
"""
......@@ -430,8 +430,8 @@ class TestCenterRegistration(models.Model):
while TestCenterRegistration.objects.filter(client_authorization_id=auth_id).exists():
auth_id = TestCenterRegistration._generate_authorization_id()
return auth_id
# methods for providing registration status details on registration page:
# methods for providing registration status details on registration page:
@property
def demographics_is_accepted(self):
return self.testcenter_user.is_accepted
......@@ -439,7 +439,7 @@ class TestCenterRegistration(models.Model):
@property
def demographics_is_rejected(self):
return self.testcenter_user.is_rejected
@property
def demographics_is_pending(self):
return self.testcenter_user.is_pending
......@@ -451,7 +451,7 @@ class TestCenterRegistration(models.Model):
@property
def accommodation_is_rejected(self):
return len(self.accommodation_request) > 0 and self.accommodation_code == ACCOMMODATION_REJECTED_CODE
@property
def accommodation_is_pending(self):
return len(self.accommodation_request) > 0 and len(self.accommodation_code) == 0
......@@ -463,20 +463,20 @@ class TestCenterRegistration(models.Model):
@property
def registration_is_accepted(self):
return self.upload_status == TEST_CENTER_STATUS_ACCEPTED
@property
def registration_is_rejected(self):
return self.upload_status == TEST_CENTER_STATUS_ERROR
@property
def registration_is_pending(self):
return not self.registration_is_accepted and not self.registration_is_rejected
# methods for providing registration status summary on dashboard page:
# methods for providing registration status summary on dashboard page:
@property
def is_accepted(self):
return self.registration_is_accepted and self.demographics_is_accepted
@property
def is_rejected(self):
return self.registration_is_rejected or self.demographics_is_rejected
......@@ -484,17 +484,17 @@ class TestCenterRegistration(models.Model):
@property
def is_pending(self):
return not self.is_accepted and not self.is_rejected
def get_accommodation_codes(self):
return self.accommodation_code.split('*')
def get_accommodation_names(self):
return [ ACCOMMODATION_CODE_DICT.get(code, "Unknown code " + code) for code in self.get_accommodation_codes() ]
return [ ACCOMMODATION_CODE_DICT.get(code, "Unknown code " + code) for code in self.get_accommodation_codes() ]
@property
def registration_signup_url(self):
return settings.PEARSONVUE_SIGNINPAGE_URL
class TestCenterRegistrationForm(ModelForm):
class Meta:
model = TestCenterRegistration
......@@ -505,33 +505,33 @@ class TestCenterRegistrationForm(ModelForm):
if code and len(code) > 0:
return code.strip()
return code
def update_and_save(self):
registration = self.save(commit=False)
# create additional values here:
registration.user_updated_at = datetime.utcnow()
registration.upload_status = ''
registration.save()
log.info("Updated registration information for user's test center exam registration: username \"{}\" course \"{}\", examcode \"{}\"".format(registration.testcenter_user.user.username, registration.course_id, registration.exam_series_code))
log.info("Updated registration information for user's test center exam registration: username \"{}\" course \"{}\", examcode \"{}\"".format(registration.testcenter_user.user.username, registration.course_id, registration.exam_series_code))
# TODO: add validation code for values added to accommodation_code field.
def get_testcenter_registration(user, course_id, exam_series_code):
try:
tcu = TestCenterUser.objects.get(user=user)
except TestCenterUser.DoesNotExist:
return []
return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id, exam_series_code=exam_series_code)
def unique_id_for_user(user):
"""
Return a unique id for a user, 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.
# different LMS installs.
h = hashlib.md5()
h.update(settings.SECRET_KEY)
h.update(str(user.id))
......
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