From d5bd2313c1baaa395bda60868f467577387a4d8b Mon Sep 17 00:00:00 2001
From: Brian Wilson <brian@edx.org>
Date: Thu, 20 Dec 2012 04:16:00 -0500
Subject: [PATCH] fix migrations, removing one field and making another
 nullable.  Update registration page to allow for editing only demographics.

---
 ...022_add_more_fields_to_test_center_user.py | 15 ++--
 common/djangoapps/student/models.py           | 13 +--
 common/djangoapps/student/views.py            | 73 ++++++++++-------
 lms/templates/dashboard.html                  |  3 +-
 lms/templates/test_center_register.html       | 80 ++++++++++++++++---
 5 files changed, 128 insertions(+), 56 deletions(-)

diff --git a/common/djangoapps/student/migrations/0022_add_more_fields_to_test_center_user.py b/common/djangoapps/student/migrations/0022_add_more_fields_to_test_center_user.py
index 4a6481f80cc..1bffec22130 100644
--- a/common/djangoapps/student/migrations/0022_add_more_fields_to_test_center_user.py
+++ b/common/djangoapps/student/migrations/0022_add_more_fields_to_test_center_user.py
@@ -13,8 +13,8 @@ class Migration(SchemaMigration):
                       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',
+        # Adding field 'TestCenterUser.uploaded_at'
+        db.add_column('student_testcenteruser', 'uploaded_at',
                       self.gf('django.db.models.fields.DateTimeField')(null=True, db_index=True),
                       keep_default=False)
 
@@ -31,14 +31,13 @@ class Migration(SchemaMigration):
             ('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)),
+            ('uploaded_at', self.gf('django.db.models.fields.DateTimeField')(null=True, db_index=True)),
             ('upload_error_message', self.gf('django.db.models.fields.CharField')(max_length=512, blank=True)),
         ))
         db.send_create_signal('student', ['TestCenterRegistration'])
@@ -51,8 +50,8 @@ class Migration(SchemaMigration):
         # 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.uploaded_at'
+        db.delete_column('student_testcenteruser', 'uploaded_at')
 
         # Deleting field 'TestCenterUser.upload_error_message'
         db.delete_column('student_testcenteruser', 'upload_error_message')
@@ -127,7 +126,7 @@ class Migration(SchemaMigration):
             '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'}),
+            'uploaded_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'}),
@@ -149,7 +148,7 @@ class Migration(SchemaMigration):
             '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'}),
+            'uploaded_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'}),
diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py
index 6b73c2319fc..716c472330e 100644
--- a/common/djangoapps/student/models.py
+++ b/common/djangoapps/student/models.py
@@ -194,7 +194,7 @@ class TestCenterUser(models.Model):
 
     # Confirmation
     upload_status = models.CharField(max_length=20, blank=True)  # 'Error' or 'Accepted'
-    confirmed_at = models.DateTimeField(null=True, db_index=True)
+    uploaded_at = models.DateTimeField(null=True, db_index=True)
     upload_error_message = models.CharField(max_length=512, blank=True)
     
     @staticmethod
@@ -236,7 +236,7 @@ class TestCenterRegistration(models.Model):
     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)
+    # 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)
@@ -250,7 +250,7 @@ class TestCenterRegistration(models.Model):
 
     # Confirmation
     upload_status = models.CharField(max_length=20, blank=True)  # 'Error' or 'Accepted'
-    confirmed_at = models.DateTimeField(db_index=True)
+    uploaded_at = models.DateTimeField(null=True, db_index=True)
     upload_error_message = models.CharField(max_length=512, blank=True)
 
     @property
@@ -261,12 +261,15 @@ class TestCenterRegistration(models.Model):
     def client_candidate_id(self):
         return self.testcenter_user.client_candidate_id
     
-    
+    @property
+    def client_authorization_id(self):
+        # TODO: make this explicitly into a string object:
+        return self.id
 
 def get_testcenter_registrations_for_user_and_course(user, course_id):
     try:
         tcu = TestCenterUser.objects.get(user=user)
-    except User.DoesNotExist:
+    except TestCenterUser.DoesNotExist:
         return []
     return TestCenterRegistration.objects.filter(testcenter_user=tcu, course_id=course_id)
     
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 4d5728792e3..62943478a01 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -10,6 +10,7 @@ import sys
 import urllib
 import uuid
 
+
 from django.conf import settings
 from django.contrib.auth import logout, authenticate, login
 from django.contrib.auth.forms import PasswordResetForm
@@ -17,6 +18,7 @@ from django.contrib.auth.models import User
 from django.contrib.auth.decorators import login_required
 from django.core.context_processors import csrf
 from django.core.mail import send_mail
+from django.core.urlresolvers import reverse
 from django.core.validators import validate_email, validate_slug, ValidationError
 from django.db import IntegrityError
 from django.http import HttpResponse, HttpResponseForbidden, Http404,\
@@ -29,7 +31,8 @@ from django.core.cache import cache
 from django_future.csrf import ensure_csrf_cookie, csrf_exempt
 from student.models import (Registration, UserProfile, TestCenterUser, TestCenterRegistration,
                             PendingNameChange, PendingEmailChange,
-                            CourseEnrollment, unique_id_for_user)
+                            CourseEnrollment, unique_id_for_user,
+                            get_testcenter_registrations_for_user_and_course)
 
 from certificates.models import CertificateStatuses, certificate_status_for_student
 
@@ -617,11 +620,7 @@ def begin_test_registration(request, course_id):
         log.error("User {0} enrolled in non-existent course {1}"
                       .format(user.username, course_id))
 
-    # TODO: placeholder for possible messages...
     message = ""
-    if not user.is_active:
-        message = render_to_string('registration/activate_account_notice.html', {'email': user.email})
-
     context = {'course': course,
                'user': user,
                'message': message,
@@ -676,7 +675,7 @@ def _do_create_or_update_test_center_user(post_vars):
         try:
             testcenter_user.save()
         except IntegrityError, ie:
-            message = ie
+            message = "%s" % ie
             context = {'course': course,
                        'user': user,
                        'message': message,
@@ -685,31 +684,45 @@ def _do_create_or_update_test_center_user(post_vars):
             return render_to_response('test_center_register.html', context)
             
     # create and save the registration:
-    registration = TestCenterRegistration(testcenter_user = testcenter_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()
-
+    needs_saving = False
+    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
+    # were multiple.
+    if len(registrations) > 0:
+        registration = registrations[0]
+        # check to see if registration changed.  Should check appointment dates too...
+        # And later should check changes in accommodation_code.
+        # But at the moment, we don't expect anything to cause this to change
+        # right now.
+        
+    else:
+        registration = TestCenterRegistration(testcenter_user = testcenter_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()
+        needs_saving = 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.
-    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)
+    # This must be present for an update or delete to be sent to Pearson.  
+    # Can we just use the id field of the registration?  Lets...
+    
+    if needs_saving:
+        try:
+            registration.save()
+        except IntegrityError, ie:
+            message = "%s" % 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)
 
 @ensure_csrf_cookie
@@ -778,7 +791,7 @@ def create_test_registration(request, post_override=None):
 
 #    js = {'success': True}
 #    return HttpResponse(json.dumps(js), mimetype="application/json")
-    return HttpResponseRedirect('/dashboard')
+    return HttpResponseRedirect(reverse('dashboard'))
 
 def get_random_post_override():
     """
diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html
index 13e393180a6..1f1553d90c9 100644
--- a/lms/templates/dashboard.html
+++ b/lms/templates/dashboard.html
@@ -234,8 +234,7 @@
                 %>
                 % 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>
+                      <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:     
diff --git a/lms/templates/test_center_register.html b/lms/templates/test_center_register.html
index 51b271dfc33..8c99b4f8ef0 100644
--- a/lms/templates/test_center_register.html
+++ b/lms/templates/test_center_register.html
@@ -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" />
 
@@ -34,14 +35,7 @@
   </script>
 </%block>
 
-<section id="testcenter-register" class="">
-    
-    
-  %if message:
-    <section class="dashboard-banner">
-      ${message}
-    </section>
-  %endif
+<section id="testcenter-register" class="">    
 
   <div class="inner-wrapper">
     <div id="register">
@@ -81,7 +75,63 @@
 
       </section>
 
-
+	<!-- check to see if the user has already registering, or
+	 	 is registering for the first time -->
+	<%	 	 
+	 	registrations = get_testcenter_registrations_for_user_and_course(user, course.id)
+	%>	
+	 
+	% if len(registrations) > 0:
+		<%	 	 
+		 	registration = registrations[0]
+		%>	
+
+		<section><div>Already Registered</div>
+			<p>Here is the current state of your registration, for debugging purposes:</p>
+			<l>
+				<li>id: ${registration.id}</li>
+				<li>testcenter_user_id: ${registration.testcenter_user_id}</li>
+				<li>course_id: ${registration.course_id}</li>
+				<li>accommodation codes: ${registration.accommodation_code}</li>
+				<li>accommodation request: ${registration.accommodation_request}</li>
+				<li>created_at: ${registration.created_at}</li>
+				<li>updated_at: ${registration.updated_at}</li>
+				<li>user_updated_at: ${registration.user_updated_at}</li>
+				<li>upload_status: ${registration.upload_status}</li>
+				<li>upload_error_message: ${registration.upload_error_message}</li>
+			</l>
+			
+			
+			<!-- determine status of registration 
+					doing here for now, but will move into model or view -->
+			<%
+				regstatus = "registration pending acknowledgement by Pearson"
+				
+				if registration.upload_status == 'Accepted':
+					regstatus = "registration approved by Pearson"
+				elif registration.upload_status == 'Error':
+					regstatus = "registration rejected by Pearson: %s" % registration.upload_error_message
+				elif len(registration.accommodation_request) > 0 and registration.accommodation_code == '':
+					regstatus = "pending approval of accommodation request"
+			%>
+			<p>Current status: ${regstatus}</p>				
+			
+			<p>The demographic information provided below was used to register
+			for the exam listed above.  Changes to this information 
+			may be submitted below.</p>
+		</section>
+	% else:
+			<p>The demographic information must be provided below in order to register
+			for the exam listed above.</p>
+	% endif
+
+	<!-- provide mechanism for error messages to appear -->
+  % if message:
+    <section class="">
+      <p>${message}</p>
+    </section>
+  % endif
+	
       <form id="test_register_form" class="test_register_form" method="post" data-remote="true" action="/create_test_registration">
         <div class="notice"></div>
         <!-- TODO: why are both of these here? -->
@@ -91,7 +141,6 @@
         <!-- include these as pass-throughs -->
         <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}" />
-        <!-- TODO: add the course somehow... -->
         <input id="id_course_id" type="hidden" name="course_id" maxlength="75" value="${course.id}" />
 
         <div class="input-group">
@@ -150,15 +199,24 @@
           <label data-field="company_name">Company</label>
           <input name="company_name" type="text" value="${testcenteruser.company_name}" placeholder="Acme Corporation">
         </div>
-
+		<div><p>The following is included here just so it can be input within the form.  But it
+			is not part of the demographics, and it is not something that can be changed once input.</p>
+        </div>
         <div class="input-group">
           <label data-field="accommodations">Accommodations Requested</label>
           <textarea name="accommodations"></textarea>
         </div>
 
+	% if len(registrations) > 0:
+        <div class="submit">
+          <input name="submit" type="submit" value="Update demographics">
+        </div>
+    % else: 
         <div class="submit">
           <input name="submit" type="submit" value="Register for Test">
         </div>
+    % endif
+    
       </form>
 
     </div>
-- 
GitLab