Index: main/waeup.aaue/trunk/src/waeup/aaue/students/studylevel.py
===================================================================
--- main/waeup.aaue/trunk/src/waeup/aaue/students/studylevel.py	(revision 14253)
+++ main/waeup.aaue/trunk/src/waeup/aaue/students/studylevel.py	(revision 14259)
@@ -182,4 +182,36 @@
         return False
 
+    def _coursePaymentsMade(self, course):
+        if not course.code[:3] in ('GST', 'ENT'):
+            return True
+        if len(self.student['payments']):
+            paid_cats = list()
+            for pticket in self.student['payments'].values():
+                if pticket.p_state == 'paid':
+                    paid_cats.append(pticket.p_category)
+            if course.code in ('GST101', 'GST102', 'GST111', 'GST112') and \
+                not 'gst_registration_1' in paid_cats:
+                return False
+            if course.code in ('GST222',) and \
+                not 'gst_registration_2' in paid_cats:
+                return False
+            if course.code in ('ENT201',) and \
+                not 'gst_registration_3' in paid_cats:
+                return False
+            if course.code in ('GST101', 'GST102') and \
+                not 'gst_text_book_1' in paid_cats:
+                return False
+            if course.code in ('GST111', 'GST112') and \
+                not 'gst_text_book_2' in paid_cats:
+                return False
+            if course.code in ('GST222',) and \
+                not 'gst_text_book_3' in paid_cats:
+                return False
+            if course.code in ('ENT201',) and \
+                not 'gst_text_book_4' in paid_cats:
+                return False
+            return True
+        return False
+
     def addCourseTicket(self, ticket, course):
         """Add a course ticket object.
@@ -194,4 +226,11 @@
                 _('%s is a 2nd semester course which can only be added '
                   'if school fees have been fully paid.' % course.code))
+        # Raise TicketError if registration fee or text
+        # book fee haven't been paid.
+        if not self._coursePaymentsMade(course):
+            raise TicketError(
+                _('%s can only be added if both registration fee and text '
+                  'book fee have been paid.'
+                  % course.code))
         ticket.code = course.code
         ticket.title = course.title
Index: main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py
===================================================================
--- main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py	(revision 14253)
+++ main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py	(revision 14259)
@@ -831,4 +831,60 @@
         return
 
+    def test_student_GST_registration(self):
+        configuration_1 = createObject('waeup.SessionConfiguration')
+        configuration_1.academic_session = 2015
+        configuration_1.gst_registration_1_fee = 3333.0
+        configuration_1.gst_text_book_1_fee = 4444.0
+        self.app['configuration'].addSessionConfiguration(configuration_1)
+        course = createObject('waeup.Course')
+        course.code = 'GST101'
+        course.semester = 1
+        course.credits = 10
+        course.passmark = 40
+        self.app['faculties']['fac1']['dep1'].courses.addCourse(
+            course)
+        self.app['faculties']['fac1']['dep1'].certificates[
+            'CERT1'].addCertCourse(course, level=100)
+        IWorkflowState(self.student).setState('school fee paid')
+        self.student['studycourse'].entry_session = 2015
+        self.student['studycourse'].current_session = 2015
+        self.course.semester = 2
+        self.browser.open(self.login_path)
+        self.browser.getControl(name="form.login").value = self.student_id
+        self.browser.getControl(name="form.password").value = 'spwd'
+        self.browser.getControl("Login").click()
+        self.browser.getLink("Study Course").click()
+        self.browser.getLink("Add course list").click()
+        self.browser.getControl("Create course list now").click()
+        self.assertFalse('GST101' in self.browser.contents)
+        # GST101 tickets can't be added manually
+        self.browser.getLink("Edit course list").click()
+        self.browser.getLink("here").click()
+        self.browser.getControl(name="form.course").value = ['GST101']
+        self.browser.getControl("Add course ticket").click()
+        self.assertTrue(
+            'GST101 can only be added if both registration fee and text'
+            in self.browser.contents)
+        # GST fees have to be paid first
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['gst_registration_1']
+        self.browser.getControl("Create ticket").click()
+        self.student['payments'].values()[0].approve()
+        self.browser.open(self.studycourse_path + '/100/ctadd')
+        self.browser.getControl(name="form.course").value = ['GST101']
+        self.browser.getControl("Add course ticket").click()
+        self.assertTrue(
+            'GST101 can only be added if both registration fee and text'
+            in self.browser.contents)
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['gst_text_book_1']
+        self.browser.getControl("Create ticket").click()
+        self.student['payments'].values()[1].approve()
+        self.browser.open(self.studycourse_path + '/100/ctadd')
+        self.browser.getControl(name="form.course").value = ['GST101']
+        self.browser.getControl("Add course ticket").click()
+        self.assertTrue('Successfully added GST101' in self.browser.contents)
+        return
+
     def test_course_registration_forbidden(self):
         IWorkflowState(self.student).setState('school fee paid')
