Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/browser.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/browser.py	(revision 13350)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/browser.py	(revision 13351)
@@ -19,4 +19,5 @@
 from zope.i18n import translate
 from zope.component import getUtility
+from zope.formlib.textwidgets import BytesDisplayWidget
 from waeup.kofa.browser.layout import UtilityView
 from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
@@ -38,13 +39,52 @@
     NigeriaExportPDFCourseRegistrationSlip,
     NigeriaExportPDFClearanceSlip,
+    NigeriaStudentPersonalDisplayFormPage,
+    NigeriaStudentPersonalEditFormPage,
+    NigeriaStudentPersonalManageFormPage,
     )
 from waeup.aaue.students.interfaces import (
     ICustomStudentOnlinePayment,
     ICustomStudentStudyLevel,
-    ICustomStudent)
+    ICustomStudent,
+    ICustomStudentPersonal,
+    ICustomStudentPersonalEdit)
 from waeup.aaue.interfaces import MessageFactory as _
 
+class CustomStudentPersonalDisplayFormPage(NigeriaStudentPersonalDisplayFormPage):
+    """ Page to display student personal data
+    """
+    form_fields = grok.AutoFields(ICustomStudentPersonal)
+    form_fields['perm_address'].custom_widget = BytesDisplayWidget
+    form_fields['father_address'].custom_widget = BytesDisplayWidget
+    form_fields['mother_address'].custom_widget = BytesDisplayWidget
+    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
+    form_fields[
+        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
+
+class CustomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
+    """ Page to edit personal data
+    """
+    form_fields = grok.AutoFields(ICustomStudentPersonalEdit).omit('personal_updated')
+
+class CustomStudentPersonalManageFormPage(NigeriaStudentPersonalManageFormPage):
+    """ Page to edit personal data
+    """
+    form_fields = grok.AutoFields(ICustomStudentPersonal)
+    form_fields['personal_updated'].for_display = True
+    form_fields[
+        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
+
 class CustomStartClearancePage(StartClearancePage):
-    with_ac = False
+    with_ac = True
+
+    @property
+    def all_required_fields_filled(self):
+        if not self.context.email:
+            return _("Email address is missing."), 'edit_base'
+        if not self.context.phone:
+            return _("Phone number is missing."), 'edit_base'
+        if not self.context.father_name:
+            return _("Personal data form is not properly filled."), 'edit_personal'
+        return
 
 class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/interfaces.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/interfaces.py	(revision 13350)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/interfaces.py	(revision 13351)
@@ -22,4 +22,5 @@
 from zope.component import getUtility
 from waeup.kofa.interfaces import IKofaObject
+from waeup.kofa.schema import PhoneNumber
 from kofacustom.nigeria.students.interfaces import (
     INigeriaStudentBase, INigeriaUGStudentClearance, INigeriaPGStudentClearance,
@@ -41,4 +42,151 @@
     """
 
+    father_name = schema.TextLine(
+        title = _(u'Father\'s Name'),
+        required = False,
+        readonly = False,
+        )
+
+    father_address = schema.Text(
+        title = _(u'Father\'s Permanent Address'),
+        required = False,
+        readonly = False,
+        )
+
+    father_work = schema.TextLine(
+        title = _(u'Father\'s Place of Work'),
+        required = False,
+        readonly = False,
+        )
+
+    father_phone = PhoneNumber(
+        title = _(u'Father\'s Phone'),
+        required = False,
+        readonly = False,
+        )
+
+    mother_name = schema.TextLine(
+        title = _(u'Mother\'s Name'),
+        required = False,
+        readonly = False,
+        )
+
+    mother_address = schema.Text(
+        title = _(u'Mother\'s Permanent Address'),
+        required = False,
+        readonly = False,
+        )
+
+    mother_work = schema.TextLine(
+        title = _(u'Mother\'s Place of Work'),
+        required = False,
+        readonly = False,
+        )
+
+    mother_phone = PhoneNumber(
+        title = _(u'Mother\'s Phone'),
+        required = False,
+        readonly = False,
+        )
+
+    phone_personal = PhoneNumber(
+        title = _(u'Student\'s Personal Phone'),
+        description = u'',
+        required = True,
+        readonly = False,
+        )
+
+class ICustomStudentPersonalEdit(ICustomStudentPersonal):
+    """Interface for editing personal data by students.
+
+    Here we can repeat the fields from IStudentPersonal and set the
+    `required` if necessary.
+    """
+
+    perm_address = schema.Text(
+        title = _(u'Permanent Address'),
+        required = True,
+        )
+
+    next_kin_name = schema.TextLine(
+        title = _(u'Next of Kin Name'),
+        required = True,
+        readonly = False,
+        )
+
+    next_kin_relation = schema.TextLine(
+        title = _(u'Next of Kin Relationship'),
+        required = True,
+        readonly = False,
+        )
+
+    next_kin_address = schema.Text(
+        title = _(u'Next of Kin Address'),
+        required = True,
+        readonly = False,
+        )
+
+    next_kin_phone = PhoneNumber(
+        title = _(u'Next of Kin Phone'),
+        description = u'',
+        required = True,
+        readonly = False,
+        )
+
+    father_name = schema.TextLine(
+        title = _(u'Father\'s Name'),
+        required = True,
+        readonly = False,
+        )
+
+    father_address = schema.Text(
+        title = _(u'Father\'s Permanent Address'),
+        required = True,
+        readonly = False,
+        )
+
+    father_work = schema.TextLine(
+        title = _(u'Father\'s Place of Work'),
+        required = True,
+        readonly = False,
+        )
+
+    father_phone = PhoneNumber(
+        title = _(u'Father\'s Phone'),
+        required = True,
+        readonly = False,
+        )
+
+    mother_name = schema.TextLine(
+        title = _(u'Mother\'s Name'),
+        required = True,
+        readonly = False,
+        )
+
+    mother_address = schema.Text(
+        title = _(u'Mother\'s Permanent Address'),
+        required = True,
+        readonly = False,
+        )
+
+    mother_work = schema.TextLine(
+        title = _(u'Mother\'s Place of Work'),
+        required = True,
+        readonly = False,
+        )
+
+    mother_phone = PhoneNumber(
+        title = _(u'Mother\'s Phone'),
+        required = True,
+        readonly = False,
+        )
+
+    phone_personal = PhoneNumber(
+        title = _(u'Student\'s Personal Phone'),
+        description = u'',
+        required = True,
+        readonly = False,
+        )
+
 class ICustomUGStudentClearance(INigeriaUGStudentClearance):
     """Representation of ug student clearance data.
Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/student.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/student.py	(revision 13350)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/student.py	(revision 13351)
@@ -25,5 +25,6 @@
 from waeup.kofa.students.interfaces import IStudentNavigation
 from kofacustom.nigeria.students.student import NigeriaStudent
-from waeup.aaue.students.interfaces import ICustomStudent
+from waeup.aaue.students.interfaces import (
+    ICustomStudent, ICustomStudentPersonalEdit)
 
 
@@ -32,5 +33,6 @@
     owned by students.
     """
-    grok.implements(ICustomStudent, IStudentNavigation)
+    grok.implements(ICustomStudent, IStudentNavigation,
+                    ICustomStudentPersonalEdit)
     grok.provides(ICustomStudent)
 
Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py	(revision 13350)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py	(revision 13351)
@@ -21,4 +21,5 @@
 import pytz
 import grok
+from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
 from datetime import datetime, timedelta, date
 from mechanize import LinkNotFoundError
@@ -33,4 +34,6 @@
 from waeup.kofa.browser.tests.test_pdf import samples_dir
 from waeup.aaue.testing import FunctionalLayer
+
+SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
 
 
@@ -493,2 +496,33 @@
         self.assertEqual(self.browser.headers['Status'], '200 Ok')
         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
+
+    def test_student_clearance(self):
+        # Student cant login if their password is not set
+        IWorkflowInfo(self.student).fireTransition('admit')
+        self.browser.open(self.login_path)
+        self.browser.getControl(name="form.login").value = self.student_id
+        self.browser.getControl(name="form.password").value = 'spwd'
+        self.browser.getControl("Login").click()
+        self.assertMatches(
+            '...You logged in...', self.browser.contents)
+        # Admitted student can upload a passport picture
+        self.browser.open(self.student_path + '/change_portrait')
+        ctrl = self.browser.getControl(name='passportuploadedit')
+        file_obj = open(SAMPLE_IMAGE, 'rb')
+        file_ctrl = ctrl.mech_control
+        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
+        self.browser.getControl(
+            name='upload_passportuploadedit').click()
+        self.assertTrue(
+            'src="http://localhost/app/students/E1000000/passport.jpg"'
+            in self.browser.contents)
+        # Student is redirected to the personal data form because
+        # personal data form is not properly filled.
+        self.browser.open(self.student_path + '/start_clearance')
+        self.assertMatches('...Personal data form is not properly filled...',
+                           self.browser.contents)
+        self.assertEqual(self.browser.url, self.student_path + '/edit_personal')
+        self.student.father_name = u'Rudolf'
+        self.browser.open(self.student_path + '/start_clearance')
+        self.assertMatches('...<h1 class="kofa-content-label">Start clearance</h1>...',
+                   self.browser.contents)
Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_export.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_export.py	(revision 13350)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_export.py	(revision 13351)
@@ -47,26 +47,29 @@
         result = open(self.outfile, 'rb').read()
         self.assertMatches(
-            'adm_code,alr_date,alr_fname,alr_no,alr_results,'
-            'clr_code,date_of_birth,def_adm,disabled,email,emp2_end,'
-            'emp2_position,emp2_reason,emp2_start,emp_end,emp_position,'
-            'emp_reason,emp_start,employer,employer2,firstname,former_matric,'
-            'fst_sit_date,fst_sit_fname,fst_sit_no,fst_sit_results,'
-            'fst_sit_type,hq2_degree,hq2_disc,hq2_matric_no,hq2_school,'
-            'hq2_session,hq2_type,hq_degree,hq_disc,hq_fname,hq_matric_no,'
-            'hq_school,hq_session,hq_type,is_staff,lastname,lga,'
-            'marit_stat,matric_number,middlename,nationality,'
-            'next_kin_address,next_kin_name,next_kin_phone,next_kin_relation,'
-            'nysc_lga,nysc_location,nysc_year,officer_comment,'
-            'perm_address,personal_updated,phone,physical_clearance_date,reg_number,'
-            'religion,scd_sit_date,scd_sit_fname,scd_sit_no,'
-            'scd_sit_results,scd_sit_type,sex,student_id,'
-            'suspended,suspended_comment,password,state,history,certcode,is_postgrad,'
-            'current_level,current_session\r\nmy adm code,,,,'
-            '"[(\'printing_craft_practice\', \'A1\')]",my clr code,1981-02-04#,,,'
-            'anna@sample.com,,,,,,,,,,,Anna,,,,,"[(\'printing_craft_practice\', \'A1\')]"'
-            ',,,,,,,,,,,,,,,,Tester,,,234,M.,NG,,,,,,,,,'
-            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,,123,,,,,'
-            '"[(\'printing_craft_practice\', \'A1\')]",,f,A111111,0,,,created,'
-            '[u\'2012-11-06 13:16:41 WAT - Record created by system\'],'
+            'adm_code,alr_date,alr_fname,alr_no,alr_results,clr_code,'
+            'date_of_birth,def_adm,disabled,email,emp2_end,emp2_position,'
+            'emp2_reason,emp2_start,emp_end,emp_position,emp_reason,'
+            'emp_start,employer,employer2,father_address,father_name,'
+            'father_phone,father_work,firstname,former_matric,fst_sit_date,'
+            'fst_sit_fname,fst_sit_no,fst_sit_results,fst_sit_type,hq2_degree,'
+            'hq2_disc,hq2_matric_no,hq2_school,hq2_session,hq2_type,'
+            'hq_degree,hq_disc,hq_fname,hq_matric_no,hq_school,hq_session,'
+            'hq_type,is_staff,lastname,lga,marit_stat,matric_number,'
+            'middlename,mother_address,mother_name,mother_phone,'
+            'mother_work,nationality,next_kin_address,next_kin_name,'
+            'next_kin_phone,next_kin_relation,nysc_lga,nysc_location,'
+            'nysc_year,officer_comment,perm_address,personal_updated,'
+            'phone,phone_personal,physical_clearance_date,reg_number,'
+            'religion,scd_sit_date,scd_sit_fname,scd_sit_no,scd_sit_results,'
+            'scd_sit_type,sex,student_id,suspended,suspended_comment,password,'
+            'state,history,certcode,is_postgrad,current_level,current_session'
+            '\r\n'
+            'my adm code,,,,"[(\'printing_craft_practice\', \'A1\')]",'
+            'my clr code,1981-02-04#,,,anna@sample.com,,,,,,,,,,,,,,,Anna,,,,,'
+            '"[(\'printing_craft_practice\', \'A1\')]",,,,,,,,,,,,,,,,Tester,,,'
+            '234,M.,,,,,NG,,,,,,,,,"Studentroad 21\nLagos 123456\n",,'
+            '+234-123-12345#,,,123,,,,,'
+            '"[(\'printing_craft_practice\', \'A1\')]",,f,A111111,0,,,'
+            'created,[u\'2015-10-26 17:45:56 WAT - Record created by system\'],'
             'CERT1,0,200,2012\r\n',
             result
