Index: main/waeup.aaue/trunk/src/waeup/aaue/applicants/browser.py
===================================================================
--- main/waeup.aaue/trunk/src/waeup/aaue/applicants/browser.py	(revision 10298)
+++ main/waeup.aaue/trunk/src/waeup/aaue/applicants/browser.py	(revision 10298)
@@ -0,0 +1,139 @@
+## $Id$
+##
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""UI components for basic applicants and related components.
+"""
+import grok
+import os
+from zope.component import getUtility
+from waeup.kofa.interfaces import (
+    IExtFileStore, IFileStoreNameChooser)
+from zope.formlib.textwidgets import BytesDisplayWidget
+from waeup.kofa.utils.helpers import string_from_bytes, file_size
+from waeup.aaue.interfaces import MessageFactory as _
+from kofacustom.nigeria.applicants.browser import (
+    NigeriaApplicantDisplayFormPage,
+    NigeriaApplicantManageFormPage,
+    NigeriaApplicantEditFormPage,
+    NigeriaPDFApplicationSlip,
+    UG_OMIT_DISPLAY_FIELDS,
+    UG_OMIT_PDF_FIELDS,
+    UG_OMIT_MANAGE_FIELDS,
+    UG_OMIT_EDIT_FIELDS,
+    PG_OMIT_DISPLAY_FIELDS,
+    PG_OMIT_PDF_FIELDS,
+    PG_OMIT_MANAGE_FIELDS,
+    PG_OMIT_EDIT_FIELDS)
+from waeup.aaue.applicants.interfaces import (
+    ICustomApplicant,
+    ICustomUGApplicant,
+    ICustomPGApplicant,
+    ICustomPGApplicantEdit,
+    ICustomUGApplicantEdit)
+
+
+class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
+    """A display view for applicant data.
+    """
+
+    @property
+    def form_fields(self):
+        if self.target is not None and self.target.startswith('pg'):
+            form_fields = grok.AutoFields(ICustomPGApplicant)
+            for field in PG_OMIT_DISPLAY_FIELDS:
+                form_fields = form_fields.omit(field)
+        else:
+            form_fields = grok.AutoFields(ICustomUGApplicant)
+            for field in UG_OMIT_DISPLAY_FIELDS:
+                form_fields = form_fields.omit(field)
+        form_fields['perm_address'].custom_widget = BytesDisplayWidget
+        form_fields['notice'].custom_widget = BytesDisplayWidget
+        if not getattr(self.context, 'student_id'):
+            form_fields = form_fields.omit('student_id')
+        if not getattr(self.context, 'screening_score'):
+            form_fields = form_fields.omit('screening_score')
+        if not getattr(self.context, 'screening_venue'):
+            form_fields = form_fields.omit('screening_venue')
+        if not getattr(self.context, 'screening_date'):
+            form_fields = form_fields.omit('screening_date')
+        return form_fields
+
+class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
+
+    note = '''
+
+The applicant has acknowledged that, if discovered at any time that she/he
+does not possess any of the qualifications which she/he claims she/he has obtained, 
+she/he will be expelled from the University and shall not be re-admitted for the same 
+or any other programme, even if she/he has upgraded her/his previous qualifications 
+or possess additional qualifications.'''
+
+    @property
+    def form_fields(self):
+        if self.target is not None and self.target.startswith('pg'):
+            form_fields = grok.AutoFields(ICustomPGApplicant)
+            for field in PG_OMIT_PDF_FIELDS:
+                form_fields = form_fields.omit(field)
+        else:
+            form_fields = grok.AutoFields(ICustomUGApplicant)
+            for field in UG_OMIT_PDF_FIELDS:
+                form_fields = form_fields.omit(field)
+        if not getattr(self.context, 'student_id'):
+            form_fields = form_fields.omit('student_id')
+        if not getattr(self.context, 'screening_score'):
+            form_fields = form_fields.omit('screening_score')
+        if not getattr(self.context, 'screening_venue'):
+            form_fields = form_fields.omit('screening_venue')
+        if not getattr(self.context, 'screening_date'):
+            form_fields = form_fields.omit('screening_date')
+        return form_fields
+
+class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
+    """A full edit view for applicant data.
+    """
+
+    @property
+    def form_fields(self):
+        if self.target is not None and self.target.startswith('pg'):
+            form_fields = grok.AutoFields(ICustomPGApplicant)
+            for field in PG_OMIT_MANAGE_FIELDS:
+                form_fields = form_fields.omit(field)
+        else:
+            form_fields = grok.AutoFields(ICustomUGApplicant)
+            for field in UG_OMIT_MANAGE_FIELDS:
+                form_fields = form_fields.omit(field)
+        form_fields['student_id'].for_display = True
+        form_fields['applicant_id'].for_display = True
+        return form_fields
+
+class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
+    """An applicant-centered edit view for applicant data.
+    """
+
+    @property
+    def form_fields(self):
+        if self.target is not None and self.target.startswith('pg'):
+            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
+            for field in PG_OMIT_EDIT_FIELDS:
+                form_fields = form_fields.omit(field)
+        else:
+            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
+            for field in UG_OMIT_EDIT_FIELDS:
+                form_fields = form_fields.omit(field)
+        form_fields['applicant_id'].for_display = True
+        form_fields['reg_number'].for_display = True
+        return form_fields
Index: main/waeup.aaue/trunk/src/waeup/aaue/applicants/interfaces.py
===================================================================
--- main/waeup.aaue/trunk/src/waeup/aaue/applicants/interfaces.py	(revision 10297)
+++ main/waeup.aaue/trunk/src/waeup/aaue/applicants/interfaces.py	(revision 10298)
@@ -20,4 +20,5 @@
 
 from zope import schema
+from zope.interface import Attribute, invariant, Invalid
 from waeup.kofa.applicants.interfaces import (
     IApplicantBaseData,
@@ -28,5 +29,7 @@
 from waeup.kofa.schema import FormattedDate, TextLineChoice
 from waeup.kofa.students.vocabularies import nats_vocab, GenderSource
-from waeup.kofa.applicants.interfaces import contextual_reg_num_source
+from waeup.kofa.applicants.interfaces import (
+    contextual_reg_num_source,
+    IApplicantBaseData)
 from kofacustom.nigeria.applicants.interfaces import (
     LGASource, high_qual, high_grade, exam_types,
@@ -40,5 +43,5 @@
 from waeup.aaue.payments.interfaces import ICustomOnlinePayment
 
-class ICustomUGApplicant(INigeriaUGApplicant):
+class ICustomUGApplicant(IApplicantBaseData):
     """An undergraduate applicant.
 
@@ -47,4 +50,162 @@
     adding them to the UG_OMIT* tuples.
     """
+
+    nationality = schema.Choice(
+        source = nats_vocab,
+        title = _(u'Nationality'),
+        required = True,
+        )
+    lga = schema.Choice(
+        source = LGASource(),
+        title = _(u'State/LGA (Nigerians only)'),
+        required = False,
+        )
+    perm_address = schema.Text(
+        title = _(u'Permanent Address'),
+        required = False,
+        )
+    course1 = schema.Choice(
+        title = _(u'1st Choice Course of Study'),
+        source = AppCatCertificateSource(),
+        required = True,
+        )
+    course2 = schema.Choice(
+        title = _(u'2nd Choice Course of Study'),
+        source = AppCatCertificateSource(),
+        required = False,
+        )
+    fst_sit_fname = schema.TextLine(
+        title = _(u'Full Name'),
+        required = False,
+        readonly = False,
+        )
+    fst_sit_no = schema.TextLine(
+        title = _(u'Exam Number'),
+        required = False,
+        readonly = False,
+        )
+    fst_sit_date = FormattedDate(
+        title = _(u'Exam Date'),
+        required = False,
+        readonly = False,
+        show_year = True,
+        )
+    fst_sit_type = schema.Choice(
+        title = _(u'Exam Type'),
+        required = False,
+        readonly = False,
+        vocabulary = exam_types,
+        )
+    fst_sit_results = schema.List(
+        title = _(u'Exam Results'),
+        value_type = ResultEntryField(),
+        required = False,
+        readonly = False,
+        default = [],
+        )
+    scd_sit_fname = schema.TextLine(
+        title = _(u'Full Name'),
+        required = False,
+        readonly = False,
+        )
+    scd_sit_no = schema.TextLine(
+        title = _(u'Exam Number'),
+        required = False,
+        readonly = False,
+        )
+    scd_sit_date = FormattedDate(
+        title = _(u'Exam Date'),
+        required = False,
+        readonly = False,
+        show_year = True,
+        )
+    scd_sit_type = schema.Choice(
+        title = _(u'Exam Type'),
+        required = False,
+        readonly = False,
+        vocabulary = exam_types,
+        )
+    scd_sit_results = schema.List(
+        title = _(u'Exam Results'),
+        value_type = ResultEntryField(),
+        required = False,
+        readonly = False,
+        default = [],
+        )
+    alr_fname = schema.TextLine(
+        title = _(u'Full Name'),
+        required = False,
+        readonly = False,
+        )
+    alr_no = schema.TextLine(
+        title = _(u'Exam Number'),
+        required = False,
+        readonly = False,
+        )
+    alr_date = FormattedDate(
+        title = _(u'Exam Date'),
+        required = False,
+        readonly = False,
+        show_year = True,
+        )
+    alr_results = schema.List(
+        title = _(u'Exam Results'),
+        value_type = ResultEntryField(),
+        required = False,
+        readonly = False,
+        default = [],
+        )
+    jamb_subjects = schema.Text(
+        title = _(u'Subjects and Scores'),
+        required = False,
+        )
+    jamb_score = schema.Int(
+        title = _(u'Total JAMB Score'),
+        required = False,
+        )
+    notice = schema.Text(
+        title = _(u'Notice'),
+        required = False,
+        )
+    screening_venue = schema.TextLine(
+        title = _(u'Screening Venue'),
+        required = False,
+        )
+    screening_date = schema.TextLine(
+        title = _(u'Screening Date'),
+        required = False,
+        )
+    screening_score = schema.Int(
+        title = _(u'Screening Score (%)'),
+        required = False,
+        )
+    aggregate = schema.Int(
+        title = _(u'Aggregate Score (%)'),
+        description = _(u'(average of relative JAMB and PUTME scores)'),
+        required = False,
+        )
+    result_uploaded = schema.Bool(
+        title = _(u'Result uploaded'),
+        default = False,
+        )
+    student_id = schema.TextLine(
+        title = _(u'Student Id'),
+        required = False,
+        readonly = False,
+        )
+    course_admitted = schema.Choice(
+        title = _(u'Admitted Course of Study'),
+        source = CertificateSource(),
+        required = False,
+        )
+    locked = schema.Bool(
+        title = _(u'Form locked'),
+        default = False,
+        )
+
+    @invariant
+    def second_choice(applicant):
+        if applicant.course1 == applicant.course2:
+            raise Invalid(_("2nd choice course must differ from 1st choice course."))
 
 class ICustomPGApplicant(INigeriaPGApplicant):
@@ -75,5 +236,5 @@
         """
 
-class ICustomUGApplicantEdit(INigeriaUGApplicantEdit):
+class ICustomUGApplicantEdit(ICustomUGApplicant):
     """An undergraduate applicant interface for edit forms.
 
