Commit e57656e2 by Brian Wilson

Add TestCenterExam class to course module, and plumb through.

parent ea8a56da
...@@ -41,6 +41,7 @@ import json ...@@ -41,6 +41,7 @@ import json
import logging import logging
import uuid import uuid
from random import randint from random import randint
from time import strftime
from django.conf import settings from django.conf import settings
...@@ -236,6 +237,15 @@ class TestCenterUser(models.Model): ...@@ -236,6 +237,15 @@ class TestCenterUser(models.Model):
testcenter_user.client_candidate_id = cand_id testcenter_user.client_candidate_id = cand_id
return testcenter_user return testcenter_user
def is_accepted(self):
return self.upload_status == 'Accepted'
def is_rejected(self):
return self.upload_status == 'Error'
def is_pending(self):
return self.upload_status == ''
class TestCenterUserForm(ModelForm): class TestCenterUserForm(ModelForm):
class Meta: class Meta:
model = TestCenterUser model = TestCenterUser
...@@ -375,13 +385,13 @@ class TestCenterRegistration(models.Model): ...@@ -375,13 +385,13 @@ class TestCenterRegistration(models.Model):
return self.testcenter_user.client_candidate_id return self.testcenter_user.client_candidate_id
@staticmethod @staticmethod
def create(testcenter_user, course_id, exam_info, accommodation_request): def create(testcenter_user, exam, accommodation_request):
registration = TestCenterRegistration(testcenter_user = testcenter_user) registration = TestCenterRegistration(testcenter_user = testcenter_user)
registration.course_id = course_id registration.course_id = exam.course_id
registration.accommodation_request = accommodation_request registration.accommodation_request = accommodation_request
registration.exam_series_code = exam_info.get('Exam_Series_Code') registration.exam_series_code = exam.exam_series_code # .get('Exam_Series_Code')
registration.eligibility_appointment_date_first = exam_info.get('First_Eligible_Appointment_Date') registration.eligibility_appointment_date_first = strftime("%Y-%m-%d", exam.first_eligible_appointment_date)
registration.eligibility_appointment_date_last = exam_info.get('Last_Eligible_Appointment_Date') registration.eligibility_appointment_date_last = strftime("%Y-%m-%d", exam.last_eligible_appointment_date)
# accommodation_code remains blank for now, along with Pearson confirmation # accommodation_code remains blank for now, along with Pearson confirmation
registration.client_authorization_id = registration._create_client_authorization_id() registration.client_authorization_id = registration._create_client_authorization_id()
return registration return registration
...@@ -404,16 +414,16 @@ class TestCenterRegistration(models.Model): ...@@ -404,16 +414,16 @@ class TestCenterRegistration(models.Model):
return auth_id return auth_id
def is_accepted(self): def is_accepted(self):
return self.upload_status == 'Accepted' return self.upload_status == 'Accepted' and self.testcenter_user.is_accepted()
def is_rejected(self): def is_rejected(self):
return self.upload_status == 'Error' return self.upload_status == 'Error' or self.testcenter_user.is_rejected()
def is_pending_accommodation(self): def is_pending_accommodation(self):
return len(self.accommodation_request) > 0 and self.accommodation_code == '' return len(self.accommodation_request) > 0 and self.accommodation_code == ''
def is_pending_acknowledgement(self): def is_pending_acknowledgement(self):
return self.upload_status == '' and not self.is_pending_accommodation() return (self.upload_status == '' or self.testcenter_user.is_pending()) and not self.is_pending_accommodation()
class TestCenterRegistrationForm(ModelForm): class TestCenterRegistrationForm(ModelForm):
class Meta: class Meta:
...@@ -430,14 +440,11 @@ class TestCenterRegistrationForm(ModelForm): ...@@ -430,14 +440,11 @@ class TestCenterRegistrationForm(ModelForm):
def get_testcenter_registrations_for_user_and_course(user, course_id, exam_series_code=None): def get_testcenter_registration(user, course_id, exam_series_code):
try: try:
tcu = TestCenterUser.objects.get(user=user) tcu = TestCenterUser.objects.get(user=user)
except TestCenterUser.DoesNotExist: except TestCenterUser.DoesNotExist:
return [] return []
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) 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):
......
...@@ -31,7 +31,7 @@ from student.models import (Registration, UserProfile, TestCenterUser, TestCente ...@@ -31,7 +31,7 @@ from student.models import (Registration, UserProfile, TestCenterUser, TestCente
TestCenterRegistration, TestCenterRegistrationForm, 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_registration)
from certificates.models import CertificateStatuses, certificate_status_for_student from certificates.models import CertificateStatuses, certificate_status_for_student
...@@ -237,6 +237,8 @@ def dashboard(request): ...@@ -237,6 +237,8 @@ def dashboard(request):
cert_statuses = { course.id: cert_info(request.user, course) for course in courses} cert_statuses = { course.id: cert_info(request.user, course) for course in courses}
exam_registrations = { course.id: exam_registration_info(request.user, course) for course in courses}
# Get the 3 most recent news # Get the 3 most recent news
top_news = _get_news(top=3) top_news = _get_news(top=3)
...@@ -247,6 +249,7 @@ def dashboard(request): ...@@ -247,6 +249,7 @@ 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,
'exam_registrations': exam_registrations,
} }
return render_to_response('dashboard.html', context) return render_to_response('dashboard.html', context)
...@@ -589,32 +592,45 @@ def create_account(request, post_override=None): ...@@ -589,32 +592,45 @@ def create_account(request, post_override=None):
js = {'success': True} js = {'success': True}
return HttpResponse(json.dumps(js), mimetype="application/json") return HttpResponse(json.dumps(js), mimetype="application/json")
def exam_registration_info(user, course):
""" Returns a Registration object if the user is currently registered for a current
exam of the course. Returns None if the user is not registered, or if there is no
current exam for the course.
"""
exam_info = course.current_test_center_exam
if exam_info is None:
return None
exam_code = exam_info.exam_series_code
registrations = get_testcenter_registration(user, course.id, exam_code)
if len(registrations) > 0:
registration = registrations[0]
else:
registration = None
return registration
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
def begin_test_registration(request, course_id): def begin_test_registration(request, course_id):
""" Handles request to register the user for the current
test center exam of the specified course. Called by form
in dashboard.html.
"""
user = request.user user = request.user
try: try:
course = (course_from_id(course_id)) course = (course_from_id(course_id))
except ItemNotFoundError: except ItemNotFoundError:
# TODO: do more than just log!! The rest will fail, so we should fail right now.
log.error("User {0} enrolled in non-existent course {1}" log.error("User {0} enrolled in non-existent course {1}"
.format(user.username, course_id)) .format(user.username, course_id))
# get the exam to be registered for: # get the exam to be registered for:
# (For now, we just assume there is one at most.) # (For now, we just assume there is one at most.)
# TODO: this should be an object, including the course_id and the exam_info = course.current_test_center_exam
# exam info for a particular exam from the course.
exam_info = course.testcenter_info
# figure out if the user is already registered for this exam: # determine if the user is registered for this course:
# (Again, for now we assume that any registration that exists is for this exam.) registration = exam_registration_info(user, course)
registrations = get_testcenter_registrations_for_user_and_course(user, course_id)
if len(registrations) > 0:
registration = registrations[0]
else:
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.
...@@ -636,12 +652,9 @@ def begin_test_registration(request, course_id): ...@@ -636,12 +652,9 @@ def begin_test_registration(request, course_id):
@ensure_csrf_cookie @ensure_csrf_cookie
def create_test_registration(request, post_override=None): def create_test_registration(request, post_override=None):
''' '''
JSON call to create test registration. JSON call to create a test center exam registration.
Used by form in test_center_register.html, which is called from Called by form in test_center_register.html
into dashboard.html
''' '''
# js = {'success': False}
post_vars = post_override if post_override else request.POST post_vars = post_override if post_override else request.POST
# first determine if we need to create a new TestCenterUser, or if we are making any update # first determine if we need to create a new TestCenterUser, or if we are making any update
...@@ -660,7 +673,6 @@ def create_test_registration(request, post_override=None): ...@@ -660,7 +673,6 @@ def create_test_registration(request, post_override=None):
testcenter_user = TestCenterUser.create(user) testcenter_user = TestCenterUser.create(user)
needs_updating = True needs_updating = 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)) log.info("User {0} enrolled in course {1} updating demographic info for test registration".format(user.username, course_id))
...@@ -678,20 +690,19 @@ def create_test_registration(request, post_override=None): ...@@ -678,20 +690,19 @@ def create_test_registration(request, post_override=None):
# create and save the registration: # create and save the registration:
needs_saving = False needs_saving = False
exam_info = course.testcenter_info exam = course.current_test_center_exam
registrations = get_testcenter_registrations_for_user_and_course(user, course_id) exam_code = exam.exam_series_code
# In future, this should check the exam series code of the registrations, if there registrations = get_testcenter_registration(user, course_id, exam_code)
# were multiple.
if len(registrations) > 0: if len(registrations) > 0:
registration = registrations[0] registration = registrations[0]
# check to see if registration changed. Should check appointment dates too... # TODO: check to see if registration changed. Should check appointment dates too...
# And later should check changes in accommodation_code. # And later should check changes in accommodation_code.
# But at the moment, we don't expect anything to cause this to change # But at the moment, we don't expect anything to cause this to change
# right now. # because of the registration form.
else: else:
accommodation_request = post_vars.get('accommodation_request','') accommodation_request = post_vars.get('accommodation_request','')
registration = TestCenterRegistration.create(testcenter_user, course_id, exam_info, accommodation_request) registration = TestCenterRegistration.create(testcenter_user, exam, accommodation_request)
needs_saving = True needs_saving = True
if needs_saving: if needs_saving:
...@@ -732,8 +743,6 @@ def create_test_registration(request, post_override=None): ...@@ -732,8 +743,6 @@ def create_test_registration(request, post_override=None):
# TODO: enable appropriate stat # TODO: enable appropriate stat
# statsd.increment("common.student.account_created") # statsd.increment("common.student.account_created")
log.info("User {0} enrolled in course {1} returning from enter/update demographic info for test registration".format(user.username, course_id))
js = {'success': True} js = {'success': True}
return HttpResponse(json.dumps(js), mimetype="application/json") return HttpResponse(json.dumps(js), mimetype="application/json")
......
...@@ -96,6 +96,21 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -96,6 +96,21 @@ class CourseDescriptor(SequenceDescriptor):
# disable the syllabus content for courses that do not provide a syllabus # disable the syllabus content for courses that do not provide a syllabus
self.syllabus_present = self.system.resources_fs.exists(path('syllabus')) self.syllabus_present = self.system.resources_fs.exists(path('syllabus'))
self.test_center_exams = []
test_center_info = self.metadata.get('testcenter_info')
if test_center_info is not None:
for exam_name in test_center_info:
try:
exam_info = test_center_info[exam_name]
self.test_center_exams.append(self.TestCenterExam(self.id, exam_name, exam_info))
except Exception as err:
# If we can't parse the test center exam info, don't break
# the rest of the courseware.
msg = 'Error %s: Unable to load test-center exam info for exam "%s" of course "%s"' % (err, exam_name, self.id)
log.error(msg)
continue
def set_grading_policy(self, policy_str): def set_grading_policy(self, policy_str):
"""Parse the policy specified in policy_str, and save it""" """Parse the policy specified in policy_str, and save it"""
try: try:
...@@ -316,24 +331,87 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -316,24 +331,87 @@ class CourseDescriptor(SequenceDescriptor):
""" """
return self.metadata.get('end_of_course_survey_url') return self.metadata.get('end_of_course_survey_url')
@property class TestCenterExam:
def testcenter_info(self): def __init__(self, course_id, exam_name, exam_info):
self.course_id = course_id
self.exam_name = exam_name
self.exam_info = exam_info
self.exam_series_code = exam_info.get('Exam_Series_Code') or exam_name
self.display_name = exam_info.get('Exam_Display_Name') or self.exam_series_code
self.first_eligible_appointment_date = self._try_parse_time('First_Eligible_Appointment_Date')
if self.first_eligible_appointment_date is None:
raise ValueError("First appointment date must be specified")
# TODO: If defaulting the last appointment date, it should be the
# *end* of the same day, not the same time. It's going to be used as the
# end of the exam overall, so we don't want the exam to disappear too soon.
# It's also used optionally as the registration end date, so time matters there too.
self.last_eligible_appointment_date = self._try_parse_time('Last_Eligible_Appointment_Date') # or self.first_eligible_appointment_date
if self.last_eligible_appointment_date is None:
raise ValueError("Last appointment date must be specified")
self.registration_start_date = self._try_parse_time('Registration_Start_Date') or time.gmtime(0)
self.registration_end_date = self._try_parse_time('Registration_End_Date') or self.last_eligible_appointment_date
# do validation within the exam info:
if self.registration_start_date > self.registration_end_date:
raise ValueError("Registration start date must be before registration end date")
if self.first_eligible_appointment_date > self.last_eligible_appointment_date:
raise ValueError("First appointment date must be before last appointment date")
if self.registration_end_date > self.last_eligible_appointment_date:
raise ValueError("Registration end date must be before last appointment date")
def _try_parse_time(self, key):
"""
Parse an optional metadata key containing a time: if present, complain
if it doesn't parse.
Return None if not present or invalid.
""" """
Pull from policy. if key in self.exam_info:
try:
return parse_time(self.exam_info[key])
except ValueError as e:
msg = "Exam {0} in course {1} loaded with a bad exam_info key '{2}': '{3}'".format(self.exam_name, self.course_id, self.exam_info[key], e)
log.warning(msg)
return None
TODO: decide if we expect this entry to be a single test, or if multiple tests are possible def has_started(self):
per course. return time.gmtime() > self.first_eligible_appointment_date
For now we expect this entry to be a single test. def has_ended(self):
return time.gmtime() > self.last_eligible_appointment_date
Returns None if no testcenter info specified, or if no exam is included. def has_started_registration(self):
""" return time.gmtime() > self.registration_start_date
info = self.metadata.get('testcenter_info')
if info is None or len(info) == 0: def has_ended_registration(self):
return None; return time.gmtime() > self.registration_end_date
else:
return info.values()[0] def is_registering(self):
now = time.gmtime()
return now >= self.registration_start_date and now <= self.registration_end_date
@property
def first_eligible_appointment_date_text(self):
return time.strftime("%b %d, %Y", self.first_eligible_appointment_date)
@property
def last_eligible_appointment_date_text(self):
return time.strftime("%b %d, %Y", self.last_eligible_appointment_date)
@property
def registration_end_date_text(self):
return time.strftime("%b %d, %Y", self.registration_end_date)
@property
def current_test_center_exam(self):
exams = [exam for exam in self.test_center_exams if exam.has_started_registration() and not exam.has_ended()]
if len(exams) > 1:
# TODO: output some kind of warning. This should already be
# caught if we decide to do validation at load time.
return exams[0]
elif len(exams) == 1:
return exams[0]
else:
return None
@property @property
def title(self): def title(self):
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
from courseware.courses import course_image_url, get_course_about_section from courseware.courses import course_image_url, get_course_about_section
from courseware.access import has_access from courseware.access import has_access
from certificates.models import CertificateStatuses from certificates.models import CertificateStatuses
from student.models import get_testcenter_registrations_for_user_and_course
%> %>
<%inherit file="main.html" /> <%inherit file="main.html" />
...@@ -220,37 +219,46 @@ ...@@ -220,37 +219,46 @@
<h3><a href="${course_target}">${course.number} ${course.title}</a></h3> <h3><a href="${course_target}">${course.number} ${course.title}</a></h3>
</hgroup> </hgroup>
<!-- TODO: need to add logic to select which of the following to display. Like certs? -->
<% <%
testcenter_info = course.testcenter_info testcenter_exam_info = course.current_test_center_exam
registration = exam_registrations.get(course.id)
testcenter_register_target = reverse('begin_test_registration', args=[course.id]) testcenter_register_target = reverse('begin_test_registration', args=[course.id])
%> %>
% if testcenter_info is not None: % if testcenter_exam_info is not None:
<!-- see if there is already a registration object % if registration is None and testcenter_exam_info.is_registering():
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"> <div class="message message-status is-shown exam-register">
<a href="${testcenter_register_target}" class="exam-button" 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> <p class="message-copy">Registration for the Pearson exam is now open.</p>
</div> </div>
% else: % endif
<div class="message message-status is-shown"> <!-- display a registration for a current exam, even if the registration period is over -->
<p class="message-copy">Your % if registration is not None:
<a href="${testcenter_register_target}" id="exam_register_link">registration for the Pearson exam</a> % if registration.is_accepted():
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"> <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>${registrations[0].client_authorization_id}</strong></p> <p class="exam-registration-number"><a href="${testcenter_register_target}" id="exam_register_link">Registration</a> number: <strong>${registration.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
% if registration.is_rejected():
<!-- TODO: revise rejection text -->
<div class="message message-status is-shown exam-schedule">
<p class="message-copy">Your
<a href="${testcenter_register_target}" id="exam_register_link">registration for the Pearson exam</a>
has been rejected. Please check the information you provided, and try to correct any demographic errors. Otherwise
contact someone at edX or Pearson, or just scream for help.</p>
</div>
% endif
% if not registration.is_accepted() and not registration.is_rejected():
<div class="message message-status is-shown">
<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>
% endif
% endif
% endif % endif
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
from courseware.courses import course_image_url, get_course_about_section from courseware.courses import course_image_url, get_course_about_section
from courseware.access import has_access from courseware.access import has_access
from certificates.models import CertificateStatuses from certificates.models import CertificateStatuses
from student.models import get_testcenter_registrations_for_user_and_course
%> %>
<%inherit file="main.html" /> <%inherit file="main.html" />
...@@ -91,12 +90,15 @@ ...@@ -91,12 +90,15 @@
<section class="status"> <section class="status">
<!-- NOTE: BT - registration data updated confirmation message - in case upon successful submit we're directing <!-- NOTE: BT - registration data updated confirmation message - in case upon successful submit we're directing
folks back to this view. To display, add "is-shown" class to div --> folks back to this view. To display, add "is-shown" class to div.
NOTE: BW - not planning to do this, but instead returning user to student dashboard.
<div class="message message-status submission-saved"> <div class="message message-status submission-saved">
<p class="message-copy">Your registration data has been updated and saved.</p> <p class="message-copy">Your registration data has been updated and saved.</p>
</div> </div>
-->
<!-- NOTE: BT - Sample markup for error message. To display, add "is-shown" class to div --> <!-- Markup for error message will be written here by ajax handler. To display, it adds "is-shown" class to div,
and adds specific error messages under the list. -->
<div class="message message-status submission-error"> <div class="message message-status submission-error">
<p id="submission-error-heading" class="message-copy"></p> <p id="submission-error-heading" class="message-copy"></p>
<ul id="submission-error-list"/> <ul id="submission-error-list"/>
...@@ -123,6 +125,7 @@ ...@@ -123,6 +125,7 @@
<input id="id_email" type="hidden" name="email" maxlength="75" value="${user.email}" /> <input id="id_email" type="hidden" name="email" maxlength="75" value="${user.email}" />
<input id="id_username" type="hidden" name="username" maxlength="75" value="${user.username}" /> <input id="id_username" type="hidden" name="username" maxlength="75" value="${user.username}" />
<input id="id_course_id" type="hidden" name="course_id" maxlength="75" value="${course.id}" /> <input id="id_course_id" type="hidden" name="course_id" maxlength="75" value="${course.id}" />
<input id="id_course_id" type="hidden" name="exam_series_code" maxlength="75" value="${exam_info.exam_series_code}" />
<div class="form-fields-primary"> <div class="form-fields-primary">
<fieldset class="group group-form group-form-personalinformation"> <fieldset class="group group-form group-form-personalinformation">
...@@ -240,14 +243,17 @@ ...@@ -240,14 +243,17 @@
<!-- Only display an accommodation request if one had been specified at registration time. <!-- Only display an accommodation request if one had been specified at registration time.
So only prompt for an accommodation request if no registration exists. So only prompt for an accommodation request if no registration exists.
BW: Bug. It is not enough to set the value of the disabled control. It does BW to BT: It is not enough to set the value of the disabled control. It does
not display any text. Perhaps we can use a different control. --> not display any text. Perhaps we can use a different markup instead of a control. -->
<ol class="list-input"> <ol class="list-input">
% if registration: % if registration:
% if registration.accommodation_request and len(registration.accommodation_request) > 0: % if registration.accommodation_request and len(registration.accommodation_request) > 0:
<li class="field disabled"> <li class="field disabled">
<label for="accommodations">Accommodations Requested</label> <label for="accommodations">Accommodations Requested</label>
<!--
<textarea class="long" id="accommodations" value="${registration.accommodation_request}" placeholder="" disabled="disabled"></textarea> <textarea class="long" id="accommodations" value="${registration.accommodation_request}" placeholder="" disabled="disabled"></textarea>
-->
<p id="accommodations">${registration.accommodation_request}</p>
</li> </li>
% endif % endif
% else: % else:
...@@ -274,30 +280,30 @@ ...@@ -274,30 +280,30 @@
% if registration: % if registration:
<h3 class="is-hidden">Registration Details</h3> <h3 class="is-hidden">Registration Details</h3>
<!-- NOTE: BT - state for if registration is accepted -->
% if registration.is_accepted(): % if registration.is_accepted():
<% regstatus = "Registration approved by Pearson" %>
<div class="message message-status registration-accepted is-shown"> <div class="message message-status registration-accepted is-shown">
<% regstatus = "Registration approved by Pearson" %>
<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">${registration.client_authorization_id}</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>
<!-- TODO: pull this link out into some settable parameter. -->
<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>
% endif % endif
% if registration.is_rejected(): % if registration.is_rejected():
<!-- NOTE: BT - state for if registration is rejected --> <!-- TODO: the registration may be failed because of the upload of the demographics or of the upload of the registration.
<% regstatus = "Registration rejected by Pearson: %s" % registration.upload_error_message %> Fix this so that the correct upload error message is displayed. -->
<div class="message message-status registration-rejected is-shown"> <div class="message message-status registration-rejected is-shown">
<% regstatus = "Registration rejected by Pearson: %s" % registration.upload_error_message %>
<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="message-copy">Your registration for the Pearson exam has been rejected. Please contact Pearson VUE for further information regarding your registration.</p> <p class="message-copy">Your registration for the Pearson exam has been rejected. Please contact Pearson VUE for further information regarding your registration.</p>
</div> </div>
% endif % endif
% if registration.is_pending_accommodation(): % if registration.is_pending_accommodation():
<% regstatus = "Registration pending approval of accommodation request" %>
<!-- NOTE: BT - state for if registration is pending -->
<div class="message message-status registration-pending is-shown"> <div class="message message-status registration-pending is-shown">
<% regstatus = "Registration pending approval of accommodation request" %>
<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="message-copy">Your registration for the Pearson exam is pending. Within a few days, you should see confirmation here of granted accommodations. <p class="message-copy">Your registration for the Pearson exam is pending. Within a few days, you should see confirmation here of granted accommodations.
At that point, your registration will be forwarded to Pearson.</p> At that point, your registration will be forwarded to Pearson.</p>
...@@ -305,9 +311,8 @@ ...@@ -305,9 +311,8 @@
% endif % endif
% if registration.is_pending_acknowledgement(): % if registration.is_pending_acknowledgement():
<% regstatus = "Registration pending acknowledgement by Pearson" %>
<!-- NOTE: BT - state for if registration is pending -->
<div class="message message-status registration-pending is-shown"> <div class="message message-status registration-pending is-shown">
<% regstatus = "Registration pending acknowledgement by Pearson" %>
<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="message-copy">Your registration for the Pearson exam is pending. Within a few days, you should see a confirmation number here, which can be used to schedule your exam.</p> <p class="message-copy">Your registration for the Pearson exam is pending. Within a few days, you should see a confirmation number here, which can be used to schedule your exam.</p>
</div> </div>
...@@ -333,16 +338,18 @@ ...@@ -333,16 +338,18 @@
<!-- NOTE: showing test details --> <!-- NOTE: showing test details -->
<h4>Pearson VUE Test Details</h4> <h4>Pearson VUE Test Details</h4>
% if exam_info is not None: % if exam_info is not None:
<!-- TODO: BT - Can we obtain a more human readable value for test-type (e.g. "Final Exam" or "Midterm Exam")? -->
<ul> <ul>
<li> <li>
<span class="label">Exam Series Code:</span> <span class="value">${exam_info.get('Exam_Series_Code')}</span> <span class="label">Exam Name:</span> <span class="value">${exam_info.display_name}</span>
</li>
<li>
<span class="label">First Eligible Appointment Date:</span> <span class="value">${exam_info.first_eligible_appointment_date_text}</span>
</li> </li>
<li> <li>
<span class="label">First Eligible Appointment Date:</span> <span class="value">${exam_info.get('First_Eligible_Appointment_Date')}</span> <span class="label">Last Eligible Appointment Date:</span> <span class="value">${exam_info.last_eligible_appointment_date_text}</span>
</li> </li>
<li> <li>
<span class="label">Last Eligible Appointment Date:</span> <span class="value">${exam_info.get('Last_Eligible_Appointment_Date')}</span> <span class="label">Registration End Date:</span> <span class="value">${exam_info.registration_end_date_text}</span>
</li> </li>
</ul> </ul>
% endif % endif
......
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