Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/applicant.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/applicant.py	(revision 15122)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/applicant.py	(revision 15123)
@@ -31,4 +31,20 @@
     grok.provides(ICustomApplicant)
 
+    def admchecking_fee_paid(self):
+        # We don't charge if admission checking fee is not set.
+        session = str(self.__parent__.year)
+        try:
+            session_config = grok.getSite()['configuration'][session]
+        except KeyError:
+            return True
+        if session_config.admchecking_fee == 0:
+            return True
+        for key in self.keys():
+            ticket = self[key]
+            if ticket.p_state == 'paid' and \
+                ticket.p_category == 'admission_checking':
+                return True
+        return False
+
 # Set all attributes of CustomApplicant required in ICustomApplicant as field
 # properties. Doing this, we do not have to set initial attributes
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser.py	(revision 15122)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser.py	(revision 15123)
@@ -19,7 +19,12 @@
 """
 import grok
+from time import time
 from zope.formlib.textwidgets import BytesDisplayWidget
+from zope.component import getUtility, createObject
+from hurry.workflow.interfaces import IWorkflowState
 from waeup.kofa.applicants.browser import (
-    ApplicantRegistrationPage, ApplicantsContainerPage)
+    ApplicantRegistrationPage, ApplicantsContainerPage,
+    ExportPDFPageApplicationSlip)
+from waeup.kofa.browser.layout import action, UtilityView
 from kofacustom.nigeria.applicants.browser import (
     NigeriaApplicantDisplayFormPage,
@@ -37,7 +42,9 @@
     PG_OMIT_EDIT_FIELDS,
     )
+from waeup.kofa.applicants.workflow import ADMITTED, PAID, STARTED
 from kofacustom.edopoly.applicants.interfaces import (
     ICustomUGApplicantEdit, ICustomUGApplicant,
-    ICustomPGApplicantEdit, ICustomPGApplicant)
+    ICustomPGApplicantEdit, ICustomPGApplicant,
+    ICustomApplicant,)
 
 from kofacustom.edopoly.interfaces import MessageFactory as _
@@ -75,4 +82,5 @@
     """A display view for applicant data.
     """
+    grok.template('applicantdisplaypage')
 
     @property
@@ -80,4 +88,6 @@
         target = getattr(self.context.__parent__, 'prefix', None)
         form_fields = grok.AutoFields(ICustomUGApplicant)
+        for field in UG_OMIT_DISPLAY_FIELDS:
+            form_fields = form_fields.omit(field)
         form_fields['notice'].custom_widget = BytesDisplayWidget
         form_fields['jamb_subjects'].custom_widget = BytesDisplayWidget
@@ -90,5 +100,97 @@
         if not getattr(self.context, 'screening_date'):
             form_fields = form_fields.omit('screening_date')
-        return form_fields
+        if not self.context.admchecking_fee_paid():
+            form_fields = form_fields.omit(
+                'screening_score', 'aggregate', 'student_id')
+        return form_fields
+
+    @property
+    def admission_checking_info(self):
+        if self.context.state == ADMITTED and \
+            not self.context.admchecking_fee_paid():
+            return _('You must pay the admission checking fee '
+                     'to view your screening results and course admitted.')
+
+    @property
+    def display_actions(self):
+        state = IWorkflowState(self.context).getState()
+        actions = []
+        if state == ADMITTED and not self.context.admchecking_fee_paid():
+            actions = [_('Add admission checking payment ticket')]
+        return actions
+
+    def getCourseAdmitted(self):
+        """Return link, title and code in html format to the certificate
+           admitted.
+        """
+        if self.admission_checking_info:
+            return self.admission_checking_info
+        return super(CustomApplicantDisplayFormPage, self).getCourseAdmitted()
+
+    @action(_('Add admission checking payment ticket'), style='primary')
+    def addPaymentTicket(self, **data):
+        self.redirect(self.url(self.context, '@@addacp'))
+        return
+
+class AdmissionCheckingFeePaymentAddPage(UtilityView, grok.View):
+    """ Page to add an admission checking online payment ticket.
+    """
+    grok.context(ICustomApplicant)
+    grok.name('addacp')
+    grok.require('waeup.payApplicant')
+    factory = u'waeup.ApplicantOnlinePayment'
+
+    def _setPaymentDetails(self, payment):
+        container = self.context.__parent__
+        timestamp = ("%d" % int(time()*10000))[1:]
+        session = str(container.year)
+        try:
+            session_config = grok.getSite()['configuration'][session]
+        except KeyError:
+            return _(u'Session configuration object is not available.'), None
+        payment.p_id = "p%s" % timestamp
+        payment.p_item = container.title
+        payment.p_session = container.year
+        payment.amount_auth = 0.0
+        payment.p_category = 'admission_checking'
+        payment.amount_auth = session_config.admchecking_fee
+        if payment.amount_auth in (0.0, None):
+            return _('Amount could not be determined.'), None
+        return
+
+    def update(self):
+        if self.context.admchecking_fee_paid():
+              self.flash(
+                  _('Admission checking payment has already been made.'),
+                  type='warning')
+              self.redirect(self.url(self.context))
+              return
+        payment = createObject(self.factory)
+        failure = self._setPaymentDetails(payment)
+        if failure is not None:
+            self.flash(failure[0], type='danger')
+            self.redirect(self.url(self.context))
+            return
+        self.context[payment.p_id] = payment
+        self.flash(_('Payment ticket created.'))
+        self.redirect(self.url(payment))
+        return
+
+    def render(self):
+        return
+
+class CustomExportPDFPageApplicationSlip(ExportPDFPageApplicationSlip):
+    """Deliver a PDF slip of the context.
+    """
+
+    def update(self):
+        super(CustomExportPDFPageApplicationSlip, self).update()
+        if self.context.state == ADMITTED and \
+            not self.context.admchecking_fee_paid():
+            self.flash(
+                _('Please pay admission checking fee before trying to download '
+                  'the application slip.'), type='warning')
+            return self.redirect(self.url(self.context))
+        return
 
 class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser_templates/applicantdisplaypage.pt
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser_templates/applicantdisplaypage.pt	(revision 15123)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/browser_templates/applicantdisplaypage.pt	(revision 15123)
@@ -0,0 +1,78 @@
+<h2 i18n:domain="waeup.kofa">
+  ...
+  <span tal:replace="context/translated_state">APPLICATIONSTATE
+  </span>
+  <span tal:omit-tag=""
+    i18n:translate="" tal:condition="context/suspended">(account suspended)
+  </span>
+  ...
+</h2>
+
+<div class="workflow">
+  <div tal:repeat="msg context/history/messages">
+    <span tal:replace="msg">MESSAGE</span><br />
+  </div>
+</div>
+
+<img src="" height="180px" tal:attributes="src view/passport_url" />
+
+<table i18n:domain="waeup.kofa" class="form-table">
+  <tbody>
+    <tal:widgets content="structure provider:widgets" />
+    <tr tal:condition="view/getCourseAdmitted">
+      <td class="fieldname" i18n:translate="">
+          Admitted Course of Study:
+      </td>
+      <td>
+        <span tal:replace="structure view/getCourseAdmitted" />
+      </td>
+    </tr>
+    <tr>
+      <td class="fieldname" i18n:translate="">
+          Password:
+      </td>
+      <td>
+          <tal:password replace="view/hasPassword" />
+      </td>
+    <tr>
+  </tbody>
+</table>
+<tal:payments condition="view/display_payments">
+  <h3 i18n:domain="waeup.kofa" i18n:translate="">
+      Payment Tickets
+  </h3>
+  <table i18n:domain="waeup.kofa" class="table table-condensed">
+    <thead>
+      <tr>
+        <th i18n:translate="">Payment Id</th>
+        <th i18n:translate="">Creation Date</th>
+        <th i18n:translate="">Payment Date</th>
+        <th i18n:translate="">Category</th>
+        <th i18n:translate="">Item</th>
+        <th i18n:translate="">State</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr tal:repeat="value context/payments">
+        <td> <a tal:attributes="href python:view.url(value)">
+        <span tal:content="value/p_id">PID</span></a></td>
+        <td tal:content="python: layout.formatDatetime(value.creation_date)">CREATION DATE</td>
+        <td tal:content="python: layout.formatDatetime(value.payment_date)">PAYMENT DATE</td>
+        <td tal:content ="value/category">CATEGORY</td>
+        <td tal:content ="value/display_item">ITEM</td>
+        <td tal:content ="value/p_state_title">STATE</td>
+      </tr>
+    </tbody>
+  </table>
+</tal:payments>
+<br />
+<form action="." tal:attributes="action request/URL" method="post"
+      i18n:domain="waeup.kofa">
+  <div tal:condition="view/availableActions">
+    <span tal:repeat="action view/actions"
+          tal:omit-tag="">
+      <input tal:condition="python:action.label in view.display_actions"
+             tal:replace="structure action/render"/>
+    </span>
+  </div>
+</form>
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/tests/test_browser.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/tests/test_browser.py	(revision 15122)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/tests/test_browser.py	(revision 15123)
@@ -31,4 +31,5 @@
 from kofacustom.edopoly.applicants.export import CustomApplicantExporter
 from kofacustom.edopoly.applicants.batching import CustomApplicantProcessor
+from kofacustom.edopoly.configuration import CustomSessionConfiguration
 
 class CustomApplicantUITests(ApplicantsFullSetup):
@@ -36,4 +37,57 @@
 
     layer = FunctionalLayer
+
+    def test_pay_admission_checking_fee(self):
+        IWorkflowState(self.applicant).setState('admitted')
+        self.applicant.screening_score = 55
+        self.applicant.course_admitted = self.certificate
+        self.login()
+        # SessionConfiguration is not set, thus admission checking payment
+        # is not necessary. Screening results and course admitted are visible.
+        self.assertFalse(
+            'Add admission checking payment ticket' in self.browser.contents)
+        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
+        self.assertTrue('<span>55</span>' in self.browser.contents)
+        configuration = CustomSessionConfiguration()
+        configuration.academic_session = datetime.datetime.now().year - 2
+        self.app['configuration'].addSessionConfiguration(configuration)
+        # Admission checking fee is 0, thus admission checking payment
+        # is not necessary. Screening results and course admitted are visible.
+        self.browser.open(self.view_path)
+        self.assertFalse(
+            'Add admission checking payment ticket' in self.browser.contents)
+        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
+        self.assertTrue('<span>55</span>' in self.browser.contents)
+        configuration.admchecking_fee = 22.0
+        # Admission checking payment button is now visible, but screening results
+        # and course admitted are not.
+        self.browser.open(self.view_path)
+        self.assertTrue(
+            'Add admission checking payment ticket' in self.browser.contents)
+        self.assertFalse('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
+        self.assertFalse('<span>55</span>' in self.browser.contents)
+        # Application slip can't be downloaded
+        self.assertFalse('Download application slip' in self.browser.contents)
+        slip_path = self.view_path + '/application_slip.pdf'
+        self.browser.open(slip_path)
+        self.assertTrue(
+            'Please pay admission checking fee before trying to download'
+            in self.browser.contents)
+        # Pay admission checking fee.
+        self.browser.getControl("Add admission checking").click()
+        p_id = self.applicant.keys()[0]
+        self.applicant[p_id].p_state = 'paid'
+        # Screening results and course admitted are visible after payment.
+        self.browser.open(self.view_path)
+        self.assertFalse(
+            'Add admission checking payment ticket' in self.browser.contents)
+        self.assertTrue('<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">CERT1 - Unnamed Certificate</a>' in self.browser.contents)
+        self.assertTrue('<span>55</span>' in self.browser.contents)
+        # Application slip can be downloaded again.
+        self.browser.getLink("Download application slip").click()
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.headers['Content-Type'],
+                         'application/pdf')
+        return
 
 class ApplicantExporterTest(ApplicantImportExportSetup):
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/viewlets.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/viewlets.py	(revision 15123)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/applicants/viewlets.py	(revision 15123)
@@ -0,0 +1,37 @@
+## $Id: viewlets.py 11599 2014-04-24 06:17:10Z henrik $
+##
+## 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
+##
+
+import grok
+from waeup.kofa.browser.viewlets import ManageActionButton
+from waeup.kofa.applicants.viewlets import PDFActionButton
+from kofacustom.edopoly.applicants.interfaces import ICustomApplicant
+from kofacustom.edopoly.interfaces import MessageFactory as _
+
+class CustomPDFActionButton(PDFActionButton):
+
+    @property
+    def target_url(self):
+        """Get a URL to the target...
+        """
+        if self.context.state in ('initialized', 'started', 'paid') \
+            or self.context.special:
+            return
+        if self.context.state == 'admitted' and \
+            not self.context.admchecking_fee_paid():
+            return
+        return self.view.url(self.view.context, self.target)
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interfaces.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interfaces.py	(revision 15122)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interfaces.py	(revision 15123)
@@ -69,4 +69,10 @@
     # Additional fees in custom package add here
 
+    admchecking_fee = schema.Float(
+        title = _(u'Admission Checking Fee'),
+        default = 0.0,
+        required = False,
+        )
+
     logbook_combo_fee = schema.Float(
         title = _(u'Logbook Combo Fee'),
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/utils/utils.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/utils/utils.py	(revision 15122)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/utils/utils.py	(revision 15123)
@@ -56,4 +56,5 @@
         'final_clearance': 'Final Clearance Fee',
         'union': 'Student Union Dues',
+        'admission_checking': 'Admission Checking Fee',
         }
 
