Index: /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/tests/test_utils.py
===================================================================
--- /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/tests/test_utils.py	(revision 12903)
+++ /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/tests/test_utils.py	(revision 12904)
@@ -1,10 +1,13 @@
 # -*- coding: utf-8 -*-
+from hurry.workflow.interfaces import IWorkflowState
+from zope.component import getUtility
 from waeup.kofa.testing import FunctionalTestCase
-from zope.component import getUtility
+from waeup.kofa.university.faculty import Faculty
+from waeup.kofa.university.department import Department
 from waeup.kofa.students.interfaces import IStudentsUtils
 from waeup.kofa.students.tests.test_browser import StudentsFullSetup
 from waeup.kwarapoly.testing import FunctionalLayer
 
-class BedAllocationTests(StudentsFullSetup):
+class StudentsUtilsTests(StudentsFullSetup):
 
     layer = FunctionalLayer
@@ -43,2 +46,38 @@
         self.assertEqual(acc_details['bt'], 'regular_male_fi')
         return
+
+    def test_setMatricNumber(self):
+        utils = getUtility(IStudentsUtils)
+        self.student.matric_number = None
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(msg, 'Matriculation number cannot be set.')
+        self.assertEqual(mnumber, None)
+        self.student['studycourse'].entry_mode = 'nd_ft'
+        self.student['studycourse'].entry_session = 2013
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(self.student.matric_number, 'ND/13/dep1/FT/001')
+        self.assertEqual(
+            self.app['faculties']['fac1']['dep1'].next_matric_dict,
+            {2013: 2})
+        # setting a new matric number in 2014, extends next_matric_dict
+        self.student['studycourse'].entry_session = 2014
+        self.student.matric_number = None
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(
+            self.app['faculties']['fac1']['dep1'].next_matric_dict,
+            {2013: 2, 2014: 2})
+        # setting a new matric number in 2014 again, increases the counter
+        self.student.matric_number = None
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(
+            self.app['faculties']['fac1']['dep1'].next_matric_dict,
+            {2013: 2, 2014: 3})
+        # matric number must not exist
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(msg, 'Matriculation number already set.')
+        # certificate must be set.
+        self.student.matric_number = None
+        self.student['studycourse'].certificate = None
+        msg, mnumber = utils.setMatricNumber(self.student)
+        self.assertEqual(msg, 'No certificate assigned.')
+        return
Index: /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py
===================================================================
--- /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py	(revision 12903)
+++ /main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py	(revision 12904)
@@ -319,4 +319,56 @@
         return d
 
+    def increaseMatricInteger(self, student):
+        """Increase counter for matric numbers.
+        """
+        cert = getattr(student.get('studycourse', None), 'certificate', None)
+        entry_session = getattr(
+            student.get('studycourse', None), 'entry_session', None)
+        dep = cert.__parent__.__parent__
+        next_matric_dict = getattr(dep, 'next_matric_dict', None)
+        if not next_matric_dict:
+            # add next_matric_dict attribute
+            dep.next_matric_dict = {}
+        if not dep.next_matric_dict.get(entry_session, None):
+            # initialize counter element
+            dep.next_matric_dict[entry_session] = 2
+            return
+        # increase counter value of entry_session
+        dep.next_matric_dict[entry_session] += 1
+        return
+
+    def constructMatricNumber(self, student):
+        """Fetch the matric number counter which fits the student and
+        construct the new matric number of the student.
+
+        A typical matriculation number is like this: ND/14/STA/FT/015
+
+        ND = Study Mode Prefix
+        14 = Year of Entry
+        STA = Department Code
+        FT = Study Mode Suffix
+        015 = Serial Number (Every department starts from "001" every
+        session and the numbers build up arithmetically)
+        """
+        cert = getattr(student.get('studycourse', None), 'certificate', None)
+        entry_session = getattr(
+            student.get('studycourse', None), 'entry_session', None)
+        entry_mode = getattr(
+            student.get('studycourse', None), 'entry_mode', None)
+        if None in (cert, entry_session, entry_mode):
+            return _('Matriculation number cannot be set.'), None
+        try:
+            (prefix, suffix) = entry_mode.split('_')
+            (prefix, suffix) = (prefix.upper(), suffix.upper())
+        except ValueError:
+            return _('Matriculation number cannot be set.'), None
+        dep = cert.__parent__.__parent__
+        next_integer = getattr(
+            dep, 'next_matric_dict', {}).get(entry_session, 1)
+        entry_year = entry_session - 100*(entry_session/100)
+        matric_number = "%s/%s/%s/%s/%03d" % (
+            prefix, entry_year, student.depcode, suffix, next_integer)
+        return None, matric_number
+
     PWCHANGE_STATES = (ADMITTED, CLEARED, RETURNING)
 
