Index: main/waeup.fceokene/trunk/src/waeup/fceokene/students/studycourse.py
===================================================================
--- main/waeup.fceokene/trunk/src/waeup/fceokene/students/studycourse.py	(revision 8474)
+++ main/waeup.fceokene/trunk/src/waeup/fceokene/students/studycourse.py	(revision 8475)
@@ -21,10 +21,11 @@
 """
 import grok
+from zope.interface import implementedBy
 from waeup.kofa.students.studycourse import (
     StudentStudyCourse, StudentStudyCourseFactory)
+from waeup.kofa.utils.helpers import attrs_to_fields
+from waeup.kofa.students.workflow import CLEARED, RETURNING, PAID
 from waeup.fceokene.students.interfaces import (
     ICustomStudentStudyCourse, IStudentNavigation)
-from zope.interface import implementedBy
-from waeup.kofa.utils.helpers import attrs_to_fields
 
 class CustomStudentStudyCourse(StudentStudyCourse):
@@ -36,10 +37,21 @@
 
     @property
-    def may_register(self):
-        if self.previous_verdict in (
-            'A','B','C','F','J','L','M','N','O','X','Z') or \
-            self.current_level in (0, 100) or\
-            (self.__parent__.current_mode.startswith('de') and self.current_level == 200) or \
-            (self.__parent__.current_mode.startswith('ph') and self.current_level == 300):
+    def next_session_allowed(self):
+        state = self.getStudent().state
+        if state == CLEARED:
+            return True
+        cond0 = state == RETURNING
+        cond1 = self.previous_verdict in (
+            'A','B','C','F','J','L','M','N','O','X','Z')
+        cond2 = self.current_level in (0, 100)
+        cond3 = self.getStudent().current_mode.startswith('de') and \
+            self.current_level == 200
+        cond4 = self.getStudent().current_mode.startswith('ph') and \
+            self.current_level == 300
+        if cond0 and (cond1 or cond2 or cond3 or cond4):
+            return True
+        cond5 = self.is_postgrad
+        cond6 = self.getStudent().state == PAID
+        if  cond5 and cond6:
             return True
         return False
Index: main/waeup.fceokene/trunk/src/waeup/fceokene/students/tests/test_browser.py
===================================================================
--- main/waeup.fceokene/trunk/src/waeup/fceokene/students/tests/test_browser.py	(revision 8474)
+++ main/waeup.fceokene/trunk/src/waeup/fceokene/students/tests/test_browser.py	(revision 8475)
@@ -113,23 +113,30 @@
         ticket = createObject(u'waeup.CourseTicket')
         verify.verifyObject(ICustomCourseTicket, ticket)
-        # Let's see if may_register works as expected
+        IWorkflowState(self.student).setState('returning')
+        # Let's see if next_session_allowed works as expected
         # A, ug_ft, 100
-        self.assertTrue(self.student['studycourse'].may_register)
+        self.assertTrue(self.student['studycourse'].next_session_allowed)
         # O, ug_ft, 100
         self.student['studycourse'].current_verdict = 'O'
-        self.assertTrue(self.student['studycourse'].may_register)
+        self.assertTrue(self.student['studycourse'].next_session_allowed)
         # O, ug_ft, 200
         self.student['studycourse'].current_level = 200
-        self.assertFalse(self.student['studycourse'].may_register)
+        self.assertFalse(self.student['studycourse'].next_session_allowed)
         # O, de_ft, 200
         self.student['studycourse'].certificate.study_mode = 'de_ft'
-        self.assertTrue(self.student['studycourse'].may_register)
+        self.assertTrue(self.student['studycourse'].next_session_allowed)
         # O, ph_ft, 300
         self.student['studycourse'].certificate.study_mode = 'ph_ft'
         self.student['studycourse'].current_level = 300
-        self.assertTrue(self.student['studycourse'].may_register)
+        self.assertTrue(self.student['studycourse'].next_session_allowed)
         # O, ph_ft, 400
         self.student['studycourse'].current_level = 400
-        self.assertFalse(self.student['studycourse'].may_register)
+        self.assertFalse(self.student['studycourse'].next_session_allowed)
+
+        # Now we convert the certificate into a postgraduate certificate
+        IWorkflowState(self.student).setState('school fee paid')
+        self.certificate.study_mode = 'pg_ft'
+        # ... and voila next session registration is allowed
+        self.assertTrue(self.student['studycourse'].next_session_allowed)
 
     def test_manage_access(self):
Index: main/waeup.fceokene/trunk/src/waeup/fceokene/students/utils.py
===================================================================
--- main/waeup.fceokene/trunk/src/waeup/fceokene/students/utils.py	(revision 8474)
+++ main/waeup.fceokene/trunk/src/waeup/fceokene/students/utils.py	(revision 8475)
@@ -17,5 +17,5 @@
 ##
 import grok
-from waeup.kofa.interfaces import CLEARED, RETURNING
+from waeup.kofa.interfaces import CLEARED, RETURNING, PAID
 from waeup.kofa.students.utils import StudentsUtils
 from waeup.kofa.students.interfaces import IStudentsUtils
@@ -96,4 +96,10 @@
                 # has paid for.
                 details['p_session'], details['p_level'] = self.getReturningData(student)
+            elif student.current_mode.startswith('pg') and student.state == PAID:
+                # Returning postgraduate students also pay for the next session
+                # but their level always remains the same.
+                details['p_session'] += 1
+                details['amount'] = getattr(
+                    student['studycourse'].certificate,'school_fee_2')
         if details['amount'] in (0.0, None):
             details['error'] = _(u'Amount could not be determined.')
