Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py	(revision 17651)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py	(revision 17661)
@@ -297,4 +297,44 @@
         )
 
+    # CDL Portal Fess only
+
+    medical_fee = schema.Float(
+        title = _(u'Medical Services Fee (CDL only)'),
+        default = 0.0,
+        required = False,
+        )
+
+
+    library_fee = schema.Float(
+        title = _(u'Library Fee (CDL only)'),
+        default = 0.0,
+        required = False,
+        )
+
+    ict_fee = schema.Float(
+        title = _(u'ICT Fee (CDL only)'),
+        default = 0.0,
+        required = False,
+        )
+
+    orientation_fee = schema.Float(
+        title = _(u'Orientation Fee (CDL only'),
+        default = 0.0,
+        required = False,
+        )
+
+    examination_fee = schema.Float(
+        title = _(u'Examination Fee (CDL only)'),
+        default = 0.0,
+        required = False,
+        )
+
+    course_fee = schema.Float(
+        title = _(u'Course Fee (CDL only)'),
+        default = 0.0,
+        required = False,
+        )
+
+
     def getSessionString():
         """Returns the session string from the vocabulary.
Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py	(revision 17651)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py	(revision 17661)
@@ -31,6 +31,10 @@
     """
 
-    # prefix
-    STUDENT_ID_PREFIX = u'I'
+    @property
+    def STUDENT_ID_PREFIX(self):
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            return u'F'
+        return u'I'
+
 
     SKIP_UPLOAD_VIEWLETS = (
@@ -125,4 +129,7 @@
         student for the payment category specified.
         """
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            return self.setCDLPaymentDetails(category, student,
+                previous_session, previous_level, combi)
         p_item = u''
         amount = 0.0
@@ -282,4 +289,133 @@
         return None, payment
 
+    def setCDLPaymentDetails(self, category, student,
+            previous_session=None, previous_level=None, combi=[]):
+        """Create a payment ticket and set the payment data of a
+        student for the payment category specified.
+        """
+        p_item = u''
+        amount = 0.0
+        if previous_session:
+            if previous_session < student['studycourse'].entry_session:
+                return _('The previous session must not fall below '
+                         'your entry session.'), None
+            if category == 'schoolfee':
+                # School fee is always paid for the following session
+                if previous_session > student['studycourse'].current_session:
+                    return _('This is not a previous session.'), None
+            else:
+                if previous_session > student['studycourse'].current_session - 1:
+                    return _('This is not a previous session.'), None
+            p_session = previous_session
+            p_level = previous_level
+            p_current = False
+        else:
+            p_session = student['studycourse'].current_session
+            p_level = student['studycourse'].current_level
+            p_current = True
+            if category in self.REQUIRED_PAYMENTS_FRESH.keys() \
+                + self.REQUIRED_PAYMENTS_RETURNING.keys() \
+                + ['schoolfee','schoolfee40','secondinstal'] \
+                and student.state == RETURNING:
+                # In case of school fee or required sundry fee payments the
+                # payment session is always next session if students are in
+                # state returning.
+                p_session, p_level = self.getReturningData(student)
+        academic_session = self._getSessionConfiguration(p_session)
+        if academic_session == None:
+            return _(u'Session configuration object is not available.'), None
+        # Determine fee.
+        if category in ('schoolfee', 'schoolfee40', 'secondinstal'):
+            rpm = self._requiredPaymentsMissing(student, p_session)
+            if rpm:
+                return rpm, None
+            try:
+                certificate = student['studycourse'].certificate
+                p_item = certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            if previous_session:
+                # Students can pay for previous sessions in all
+                # workflow states.  Fresh students are excluded by the
+                # update method of the PreviousPaymentAddFormPage.
+                if previous_level == 100:
+                    amount = getattr(certificate, 'school_fee_1', 0.0)
+                else:
+                    amount = getattr(certificate, 'school_fee_2', 0.0)
+                if category == 'schoolfee40':
+                    amount = 0.4*amount
+                elif category == 'secondinstal':
+                    amount = 0.6*amount
+            else:
+                if category == 'secondinstal':
+                    if student.is_fresh:
+                        amount = 0.6 * getattr(certificate, 'school_fee_1', 0.0)
+                    else:
+                        amount = 0.6 * getattr(certificate, 'school_fee_2', 0.0)
+                else:
+                    if student.state in (CLEARANCE, REQUESTED, CLEARED):
+                        amount = getattr(certificate, 'school_fee_1', 0.0)
+                    elif student.state == RETURNING:
+                        amount = getattr(certificate, 'school_fee_2', 0.0)
+                    elif student.is_postgrad and student.state == PAID:
+                        # Returning postgraduate students also pay for the
+                        # next session but their level always remains the
+                        # same.
+                        p_session += 1
+                        academic_session = self._getSessionConfiguration(p_session)
+                        if academic_session == None:
+                            return _(
+                                u'Session configuration object is not available.'
+                                ), None
+                        amount = getattr(certificate, 'school_fee_2', 0.0)
+                    if amount and category == 'schoolfee40':
+                        amount = 0.4*amount
+        elif category == 'clearance':
+            try:
+                p_item = student['studycourse'].certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            amount = academic_session.clearance_fee
+        elif category.startswith('cdlcourse'):
+            amount = academic_session.course_fee
+            number = int(category.strip('cdlcourse'))
+            amount *= number
+        elif category == 'combi' and combi:
+            categories = getUtility(IKofaUtils).CDLPORTAL_PAYMENT_CATEGORIES
+            for cat in combi:
+                fee_name = cat + '_fee'
+                cat_amount = getattr(academic_session, fee_name, 0.0)
+                if not cat_amount:
+                    return _('%s undefined.' % categories[cat]), None
+                amount += cat_amount
+                p_item += u'%s + ' % categories[cat]
+            p_item = p_item.strip(' + ')
+        else:
+            fee_name = category + '_fee'
+            amount = getattr(academic_session, fee_name, 0.0)
+        if amount in (0.0, None):
+            return _('Amount could not be determined.'), None
+        if self.samePaymentMade(student, category, p_item, p_session):
+            return _('This type of payment has already been made.'), None
+        if self._isPaymentDisabled(p_session, category, student):
+            return _('This category of payments has been disabled.'), None
+        payment = createObject(u'waeup.StudentOnlinePayment')
+        timestamp = ("%d" % int(time()*10000))[1:]
+        if category in (
+            'registration', 'required_combi', 'pg_other', 'jupeb_reg'):
+            payment.provider_amt = 5000.0
+        if category in (
+            'schoolfee', 'schoolfee40') and student.is_jupeb:
+            payment.provider_amt = 5000.0
+        payment.p_id = "p%s" % timestamp
+        payment.p_category = category
+        payment.p_item = p_item
+        payment.p_session = p_session
+        payment.p_level = p_level
+        payment.p_current = p_current
+        payment.amount_auth = amount
+        payment.p_combi = combi
+        return None, payment
+
     def setBalanceDetails(self, category, student,
             balance_session, balance_level, balance_amount):
Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/viewlets.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/viewlets.py	(revision 17651)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/viewlets.py	(revision 17661)
@@ -37,4 +37,12 @@
 from kofacustom.nigeria.interfaces import MessageFactory as _
 
+class AddPreviousPaymentActionButton(AddPreviousPaymentActionButton):
+
+    @property
+    def target(self):
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            return
+        return 'addpp'
+
 class StudentPersonalEditActionButton(StudentPersonalEditActionButton):
     text = _('Edit registration bio data')
@@ -110,4 +118,17 @@
         #if self.context.student.depcode == 'BMS':
         #    return ''
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            return
+        return self.view.url(self.view.context, self.target)
+
+class AddPreviousPaymentActionButton(AddPreviousPaymentActionButton):
+
+    @property
+    def target_url(self):
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            return
+        student = self.view.context.student
+        if student.before_payment or not self.target:
+            return ''
         return self.view.url(self.view.context, self.target)
 
Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py	(revision 17651)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py	(revision 17661)
@@ -19,4 +19,5 @@
 """
 
+import grok
 from copy import deepcopy
 from kofacustom.nigeria.utils.utils import NigeriaKofaUtils
@@ -68,5 +69,5 @@
         'resit4': '4 Make-Up Examination Courses',
         'resit5': '5 Make-Up Examination Courses',
-        'resit6': '6 Make-Up Examination Course',
+        'resit6': '6 Make-Up Examination Courses',
         'resit7': '7 Make-Up Examination Courses',
         'resit8': '8 Make-Up Examination Courses',
@@ -84,4 +85,25 @@
         'brought_fwd': 'Balance Brought Forward',
         'health_insurance': 'Student Health Insurance',
+        # CDL Portal Fees only
+        'medical':'Medical Services',
+        'library':'Library',
+        'ict':'ICT Fees',
+        'orientation':'Orientation Fee',
+        'examination':'Examination Fee',
+        'cdlcourse1': ' 1 Course',
+        'cdlcourse2': ' 2 Courses',
+        'cdlcourse3': ' 3 Courses',
+        'cdlcourse4': ' 4 Courses',
+        'cdlcourse5': ' 5 Courses',
+        'cdlcourse6': ' 6 Courses',
+        'cdlcourse7': ' 7 Courses',
+        'cdlcourse8': ' 8 Courses',
+        'cdlcourse9': ' 9 Courses',
+        'cdlcourse10': '10 Courses',
+        'cdlcourse11': '11 Courses',
+        'cdlcourse12': '12 Courses',
+        'cdlcourse13': '13 Courses',
+        'cdlcourse14': '14 Courses',
+        'cdlcourse15': '15 Courses',
         }
 
@@ -127,5 +149,5 @@
         #'resit4': '4 Make-Up Examination Courses',
         #'resit5': '5 Make-Up Examination Courses',
-        #'resit6': '6 Make-Up Examination Course',
+        #'resit6': '6 Make-Up Examination Courses',
         #'resit7': '7 Make-Up Examination Courses',
         #'resit8': '8 Make-Up Examination Courses',
@@ -144,5 +166,35 @@
         }
 
+    CDLPORTAL_PAYMENT_CATEGORIES = {
+        'clearance': 'Acceptance Fee',
+        'id_card': 'Student ID Card',
+        'waecneco': 'WAEC/NECO Verification',
+        # CDL Portal fees only
+        'medical':'Medical Services',
+        'library':'Library',
+        'ict':'ICT Fees',
+        'orientation':'Orientation Fee',
+        'examination':'Examination Fee',
+        'cdlcourse1': ' 1 Course',
+        'cdlcourse2': ' 2 Courses',
+        'cdlcourse3': ' 3 Courses',
+        'cdlcourse4': ' 4 Courses',
+        'cdlcourse5': ' 5 Courses',
+        'cdlcourse6': ' 6 Courses',
+        'cdlcourse7': ' 7 Courses',
+        'cdlcourse8': ' 8 Courses',
+        'cdlcourse9': ' 9 Courses',
+        'cdlcourse10': '10 Courses',
+        'cdlcourse11': '11 Courses',
+        'cdlcourse12': '12 Courses',
+        'cdlcourse13': '13 Courses',
+        'cdlcourse14': '14 Courses',
+        'cdlcourse15': '15 Courses',
+        }
+
     def selectable_payment_categories(self, student):
+        if grok.getSite().__name__ == 'iuokada-cdl':
+            spc = deepcopy(self.CDLPORTAL_PAYMENT_CATEGORIES)
+            return spc
         spc = deepcopy(self.SELECTABLE_PAYMENT_CATEGORIES)
         if student.depcode == 'BMS':
