Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/browser/pages.py
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/browser/pages.py	(revision 15175)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/browser/pages.py	(revision 15176)
@@ -19,8 +19,17 @@
 from waeup.kofa.browser.pages import (
     SessionConfigurationAddFormPage, SessionConfigurationManageFormPage,
-    LoginPage, CertificatePage, CertificateManageFormPage)
+    LoginPage, CertificatePage, CertificateManageFormPage,
+    ConfigurationContainerManageFormPage)
+from waeup.kofa.interfaces import IConfigurationContainer
 from waeup.kofa.university.interfaces import ICertificate
 from kofacustom.edopoly.interfaces import (
     ICustomSessionConfiguration, ICustomSessionConfigurationAdd)
+
+class CustomConfigurationContainerManageFormPage(
+    ConfigurationContainerManageFormPage):
+
+    form_fields = grok.AutoFields(IConfigurationContainer).omit(
+        'frontpage_dict')
+    form_fields['maintmode_enabled_by'].for_display = True
 
 class CustomSessionConfigurationAddFormPage(SessionConfigurationAddFormPage):
Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/locales/en/LC_MESSAGES/waeup.kofa.po
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/locales/en/LC_MESSAGES/waeup.kofa.po	(revision 15175)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/locales/en/LC_MESSAGES/waeup.kofa.po	(revision 15176)
@@ -30,2 +30,31 @@
 msgid "Foreigner Returning School Fee"
 msgstr "Tuition Fee 4 (not used)"
+
+msgid "Next Matriculation Number Integer"
+msgstr "Next ND-FT Matriculation Number Integer"
+
+msgid "Integer used for constructing the next matriculation number"
+msgstr ""
+"Integer used for constructing the next matriculation number of ND-FT students"
+
+msgid "Next Matriculation Number Integer 2"
+msgstr "Next HND-FT Matriculation Number Integer"
+
+msgid "2nd integer used for constructing the next matriculation number"
+msgstr ""
+"Integer used for constructing the next matriculation number of HND-FT students"
+
+msgid "Next Matriculation Number Integer 3"
+msgstr "Next ND-PT Matriculation Number Integer"
+
+msgid "3rd integer used for constructing the next matriculation number"
+msgstr ""
+"Integer used for constructing the next matriculation number of ND-PT students"
+
+msgid "Next Matriculation Number Integer 4"
+msgstr "Next HND-PT Matriculation Number Integer"
+
+msgid "4th integer used for constructing the next matriculation number"
+msgstr ""
+"Integer used for constructing the next matriculation number of HND-PT "
+"students"
Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/browser.py
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/browser.py	(revision 15175)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/browser.py	(revision 15176)
@@ -23,6 +23,6 @@
 from waeup.kofa.interfaces import REQUESTED, IExtFileStore, IKofaUtils
 from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
-from waeup.kofa.browser.layout import KofaEditFormPage
-from waeup.kofa.browser.layout import action, jsaction
+from waeup.kofa.browser.layout import (
+    KofaEditFormPage, UtilityView, action, jsaction)
 from waeup.kofa.students.browser import (
     StudyLevelEditFormPage, StudyLevelDisplayFormPage,
@@ -31,5 +31,6 @@
     BedTicketAddPage, ExportPDFTranscriptSlip,
     msave, emit_lock_message)
-from waeup.kofa.students.interfaces import IStudentsUtils, ICourseTicket
+from waeup.kofa.students.interfaces import (
+    IStudentsUtils, ICourseTicket, IStudent)
 from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS
 from kofacustom.nigeria.students.browser import (
@@ -41,8 +42,7 @@
     NigeriaExportPDFClearanceSlip,
     )
-
 from kofacustom.edopoly.students.interfaces import (
     ICustomStudentOnlinePayment, ICustomStudentStudyCourse,
-    ICustomStudentStudyLevel)
+    ICustomStudentStudyLevel, ICustomStudent)
 from kofacustom.edopoly.interfaces import MessageFactory as _
 
@@ -146,2 +146,62 @@
             return
         return
+
+class StudentGetMatricNumberPage(UtilityView, grok.View):
+    """ Construct and set the matriculation number.
+    """
+    grok.context(IStudent)
+    grok.name('get_matric_number')
+    grok.require('waeup.viewStudent')
+
+    def update(self):
+        students_utils = getUtility(IStudentsUtils)
+        msg, mnumber = students_utils.setMatricNumber(self.context)
+        if msg:
+            self.flash(msg, type="danger")
+        else:
+            self.flash(_('Matriculation number %s assigned.' % mnumber))
+            self.context.writeLogMessage(self, '%s assigned' % mnumber)
+        self.redirect(self.url(self.context))
+        return
+
+    def render(self):
+        return
+
+class ExportPDFMatricNumberSlip(UtilityView, grok.View):
+    """Deliver a PDF notification slip.
+    """
+    grok.context(ICustomStudent)
+    grok.name('matric_number_slip.pdf')
+    grok.require('waeup.viewStudent')
+    prefix = 'form'
+
+    form_fields = grok.AutoFields(ICustomStudent).select(
+        'student_id', 'matric_number')
+    omit_fields = ('date_of_birth', 'current_level', 'flash_notice')
+
+    @property
+    def title(self):
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        return translate(_('Matriculation Number'), 'waeup.kofa',
+            target_language=portal_language)
+
+    @property
+    def label(self):
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        return translate(_('Matriculation Number Slip\n'),
+            target_language=portal_language) \
+            + ' %s' % self.context.display_fullname
+
+    def render(self):
+        if self.context.state not in (PAID,) or not self.context.is_fresh \
+            or not self.context.matric_number:
+            self.flash('Not allowed.', type="danger")
+            self.redirect(self.url(self.context))
+            return
+        students_utils = getUtility(IStudentsUtils)
+        pre_text = _('Congratulations! Your acceptance fee and school fees ' +
+                     'payments have been received and your matriculation ' +
+                     'number generated with details as follows.')
+        return students_utils.renderPDFAdmissionLetter(self,
+            self.context.student, omit_fields=self.omit_fields,
+            pre_text=pre_text, post_text='')
Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/tests/test_utils.py
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/tests/test_utils.py	(revision 15176)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/tests/test_utils.py	(revision 15176)
@@ -0,0 +1,57 @@
+## $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
+##
+import grok
+from hurry.workflow.interfaces import IWorkflowState
+from zope.component import getUtility, createObject
+from waeup.kofa.students.studylevel import StudentStudyLevel
+from waeup.kofa.students.tests.test_browser import StudentsFullSetup
+from waeup.kofa.students.interfaces import IStudentsUtils
+from waeup.kofa.students.studylevel import StudentStudyLevel
+from kofacustom.edopoly.testing import FunctionalLayer
+
+class StudentsUtilsTests(StudentsFullSetup):
+
+    layer = FunctionalLayer
+
+    def test_setMatricNumber(self):
+        IWorkflowState(self.student).setState('school fee paid')
+        site = grok.getSite()
+        utils = getUtility(IStudentsUtils)
+        site['configuration'].next_matric_integer = 1
+        site['configuration'].next_matric_integer_2 = 1
+        site['configuration'].next_matric_integer_3 = 1
+        site['configuration'].next_matric_integer_4 = 1
+        self.student.matric_number = None
+        # nd_ft
+        self.certificate.study_mode ='nd_ft'
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(self.student.matric_number, 'ESITM/fac1/dep1/04/00001')
+        self.assertEqual(msg, None)
+        # hnd_ft
+        self.student.matric_number = None
+        self.certificate.study_mode ='hnd_ft'
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(self.student.matric_number, 'ESITM/fac1/dep1/HND/04/00001')
+        self.assertEqual(msg, None)
+        # nd_pt
+        self.student.matric_number = None
+        self.certificate.study_mode ='nd_pt'
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(self.student.matric_number, 'ESITM/PT-ND/fac1/dep1/04/00001')
+        self.assertEqual(msg, None)
+        return
Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py	(revision 15175)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py	(revision 15176)
@@ -17,4 +17,5 @@
 ##
 from time import time
+import grok
 from zope.component import createObject, getUtility
 from waeup.kofa.interfaces import (IKofaUtils,
@@ -246,2 +247,40 @@
         payment.amount_auth = amount
         return None, payment
+
+    def constructMatricNumber(self, student):
+        faccode = student.faccode
+        depcode = student.depcode
+        certcode = student.certcode
+        year = unicode(student.entry_session)[2:]
+        if not student.state in (PAID, ) or not student.is_fresh:
+            return _('Matriculation number cannot be set.'), None
+
+        # ESITM/ENG/MEC/11/5367
+        if student.current_mode == 'nd_ft':
+            next_integer = grok.getSite()['configuration'].next_matric_integer
+            if next_integer == 0:
+                return _('Matriculation number cannot be set.'), None
+            return None, "ESITM/%s/%s/%s/%05d" % (
+                faccode, depcode, year, next_integer)
+
+        # ESITM/ENG/MEC/HND/11/5367
+        if student.current_mode == 'hnd_ft':
+            next_integer = grok.getSite()['configuration'].next_matric_integer_2
+            if next_integer == 0:
+                return _('Matriculation number cannot be set.'), None
+            return None, "ESITM/%s/%s/HND/%s/%05d" % (
+                faccode, depcode, year, next_integer)
+
+        # ESITM/PT-ND/ENG/MEC/11/5367
+        if student.current_mode == 'nd_pt':
+            next_integer = grok.getSite()['configuration'].next_matric_integer_3
+            if next_integer == 0:
+                return _('Matriculation number cannot be set.'), None
+            return None, "ESITM/PT-ND/%s/%s/%s/%05d" % (
+                faccode, depcode, year, next_integer)
+
+        # ???
+        if student.current_mode == 'hnd_pt':
+            pass
+
+        return _('Matriculation number cannot be set.'), None
Index: main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/viewlets.py
===================================================================
--- main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/viewlets.py	(revision 15175)
+++ main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/viewlets.py	(revision 15176)
@@ -20,11 +20,49 @@
 from waeup.kofa.interfaces import REQUESTED
 from waeup.kofa.browser.viewlets import ManageActionButton
-from kofacustom.edopoly.students.interfaces import (
-    ICustomStudentStudyCourse, ICustomStudentStudyLevel)
 from waeup.kofa.students.fileviewlets import (
     StudentFileDisplay, StudentFileUpload, StudentImage)
 from waeup.kofa.students.browser import (
     ExportPDFClearanceSlip, StudyCourseDisplayFormPage,
-    StudyLevelDisplayFormPage)
+    StudyLevelDisplayFormPage, StudentBaseDisplayFormPage)
+from waeup.kofa.students.interfaces import IStudent
+
+from kofacustom.edopoly.students.interfaces import (
+    ICustomStudentStudyCourse, ICustomStudentStudyLevel)
 
 from kofacustom.nigeria.interfaces import MessageFactory as _
+
+class GetMatricNumberActionButton(ManageActionButton):
+    grok.order(10)
+    grok.context(IStudent)
+    grok.view(StudentBaseDisplayFormPage)
+    grok.require('waeup.viewStudent')
+    #grok.require('waeup.manageStudent')
+    icon = 'actionicon_count.png'
+    text = _('Get Matriculation Number')
+
+    @property
+    def target_url(self):
+        students_utils = getUtility(IStudentsUtils)
+        if self.context.matric_number:
+            return ''
+        error, matric_number = students_utils.constructMatricNumber(
+            self.context)
+        if error:
+            return ''
+        return self.view.url(self.view.context, 'get_matric_number')
+
+class MatricNumberSlipActionButton(ManageActionButton):
+    grok.order(10)
+    grok.context(IStudent)
+    grok.view(StudentBaseDisplayFormPage)
+    grok.require('waeup.viewStudent')
+    icon = 'actionicon_pdf.png'
+    text = _('Download matriculation number slip')
+    target = 'matric_number_slip.pdf'
+
+    @property
+    def target_url(self):
+        if self.context.state not in (PAID,) or not self.context.is_fresh \
+            or not self.context.matric_number:
+            return ''
+        return self.view.url(self.view.context, self.target)
