Index: main/waeup.uniben/trunk/src/waeup/uniben/applicants/browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/applicants/browser.py	(revision 16775)
+++ main/waeup.uniben/trunk/src/waeup/uniben/applicants/browser.py	(revision 16804)
@@ -53,5 +53,6 @@
     ICustomUGApplicantEdit,
     IPUTMEApplicantEdit,
-    ITranscriptApplicant)
+    ITranscriptApplicant,
+    IFrenchApplicant)
 from waeup.kofa.applicants.workflow import ADMITTED, PAID, STARTED
 from kofacustom.nigeria.applicants.interfaces import (
@@ -257,4 +258,9 @@
             #form_fields['perm_address'].custom_widget = BytesDisplayWidget
             return form_fields
+        if self.target is not None and self.target == 'french':
+            form_fields = grok.AutoFields(IFrenchApplicant)
+            for field in REGISTRATION_OMIT_DISPLAY_FIELDS:
+                form_fields = form_fields.omit(field)
+            return form_fields
         if self.target == 'ictwk':
             form_fields = grok.AutoFields(IUnibenRegistration)
@@ -452,4 +458,9 @@
                 form_fields['registration_cats'].for_display = True
             return form_fields
+        if self.target is not None and self.target == 'french':
+            form_fields = grok.AutoFields(IFrenchApplicant)
+            for field in REGISTRATION_OMIT_MANAGE_FIELDS:
+                form_fields = form_fields.omit(field)
+            return form_fields
         if self.target is not None and self.target.startswith('pg'):
             form_fields = grok.AutoFields(ICustomPGApplicant)
@@ -511,7 +522,7 @@
             for field in TRANS_OMIT_EDIT_FIELDS:
                 form_fields = form_fields.omit(field)
-                form_fields = form_fields.omit('locked')
             if state == PAID:
                 form_fields['order'].for_display = True
+            form_fields = form_fields.omit('locked')
             return form_fields
         if self.target is not None and self.target == 'tscs':
@@ -521,5 +532,5 @@
             for field in TRANS_SHORT_OMIT_EDIT_FIELDS:
                 form_fields = form_fields.omit(field)
-                form_fields = form_fields.omit('locked')
+            form_fields = form_fields.omit('locked')
             if state == PAID:
                 form_fields['order'].for_display = True
@@ -531,4 +542,9 @@
             if state != STARTED:
                 form_fields['registration_cats'].for_display = True
+            return form_fields
+        if self.target is not None and self.target == 'french':
+            form_fields = grok.AutoFields(IFrenchApplicant)
+            for field in REGISTRATION_OMIT_EDIT_FIELDS:
+                form_fields = form_fields.omit(field)
             return form_fields
         if self.target is not None and self.target.startswith('pg'):
@@ -705,4 +721,8 @@
                 for field in PUDE_OMIT_PDF_FIELDS:
                     form_fields = form_fields.omit(field)
+        elif self.target is not None and self.target == 'french':
+            form_fields = grok.AutoFields(IFrenchApplicant)
+            for field in REGISTRATION_OMIT_PDF_FIELDS:
+                form_fields = form_fields.omit(field)
         else:
             form_fields = grok.AutoFields(ICustomUGApplicant)
Index: main/waeup.uniben/trunk/src/waeup/uniben/applicants/interfaces.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/applicants/interfaces.py	(revision 16775)
+++ main/waeup.uniben/trunk/src/waeup/uniben/applicants/interfaces.py	(revision 16804)
@@ -142,4 +142,21 @@
             return _('Certified True Copy')
 
+class ProficiencySource(BasicSourceFactory):
+    """
+    """
+    def getValues(self):
+        return ['n', 'c', 'p']
+
+    def getToken(self, value):
+        return value
+
+    def getTitle(self, value):
+        if value == 'n':
+            return _('none')
+        if value == 'c':
+            return _('conversational')
+        if value == 'c':
+            return _('professional')
+
 class IUnibenRegistration(IKofaObject):
     """A Uniben registrant.
@@ -444,4 +461,100 @@
             raise Invalid(_("You've selected the wrong transcript charge."))
 
+class IFrenchApplicant(IKofaObject):
+    """A transcript applicant.
+    """
+
+    suspended = schema.Bool(
+        title = _(u'Account suspended'),
+        default = False,
+        required = False,
+        )
+
+    locked = schema.Bool(
+        title = _(u'Form locked'),
+        default = False,
+        required = False,
+        )
+
+    applicant_id = schema.TextLine(
+        title = _(u'Applicant Id'),
+        required = False,
+        readonly = False,
+        )
+
+    firstname = schema.TextLine(
+        title = _(u'First Name'),
+        required = True,
+        )
+
+    middlename = schema.TextLine(
+        title = _(u'Middle Name'),
+        required = False,
+        )
+
+    lastname = schema.TextLine(
+        title = _(u'Surname'),
+        required = True,
+        )
+
+    date_of_birth = FormattedDate(
+        title = _(u'Date of Birth'),
+        required = False,
+        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
+        show_year = True,
+        )
+
+    sex = schema.Choice(
+        title = _(u'Gender'),
+        source = GenderSource(),
+        required = True,
+        )
+
+    nationality = schema.Choice(
+        vocabulary = nats_vocab,
+        title = _(u'Nationality'),
+        required = False,
+        )
+
+    email = schema.ASCIILine(
+        title = _(u'Email Address'),
+        required = True,
+        constraint=validate_email,
+        )
+
+    phone = PhoneNumber(
+        title = _(u'Phone'),
+        description = u'',
+        required = False,
+        )
+
+    work = schema.TextLine(
+        title = _(u'Place of Work'),
+        required = False,
+        )
+
+    hq_obtained = schema.Choice(
+        title = _(u'Highest Qualification Obtained'),
+        required = False,
+        readonly = False,
+        vocabulary = high_qual,
+        )
+
+    hq_date = FormattedDate(
+        title = _(u'Highest Qualification Date'),
+        required = False,
+        readonly = False,
+        show_year = True,
+        )
+    proficiency = schema.Choice(
+        source = ProficiencySource(),
+        title = _(u'Level of Proficiency'),
+        required = False,
+        )
+
+    guarantor = schema.TextLine(
+        title = _(u'Name of Guarantor'),
+        required = False,
+        )
 
 class ICustomUGApplicant(IApplicantBaseData, IBankAccount):
@@ -670,5 +783,5 @@
 
 class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
-    IUnibenRegistration, ITranscriptApplicant):
+    IUnibenRegistration, ITranscriptApplicant, IFrenchApplicant):
     """An interface for both types of applicants.
 
Index: main/waeup.uniben/trunk/src/waeup/uniben/applicants/utils.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/applicants/utils.py	(revision 16775)
+++ main/waeup.uniben/trunk/src/waeup/uniben/applicants/utils.py	(revision 16804)
@@ -68,4 +68,5 @@
         'tscf': ['Transcript (without student record)', 'TRF'],
         'tscs': ['Transcript (with student record)', 'TRS'],
+        'french': ['French Language Centre', 'FR'],
         }
 
