Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interswitch/tests.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interswitch/tests.py	(revision 17390)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/interswitch/tests.py	(revision 17391)
@@ -62,5 +62,5 @@
         self.browser.getControl("Create ticket").click()
         self.assertTrue(
-            'Pay ICT and Logbook fee(s) first.' in self.browser.contents)
+            'Pay ICT, Student Union and Logbook fee(s) first.' in self.browser.contents)
 
         # Add required payments first.
@@ -83,4 +83,10 @@
         payment.p_session = 2004
         self.student['payments']['345'] = payment
+        payment = createObject('waeup.StudentOnlinePayment')
+        payment.p_state = 'paid'
+        payment.p_category = 'union'
+        payment.p_id = '567'
+        payment.p_session = 2004
+        self.student['payments']['567'] = payment
 
         self.browser.open(self.payments_path + '/addop')
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 17390)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/tests/test_utils.py	(revision 17391)
@@ -71,6 +71,8 @@
         self.app['configuration']['2004'].ict_entre_fee = 4170.0
         self.app['configuration']['2005'].ict_entre_fee = 2180.0
+        self.app['configuration']['2004'].union_fee = 1234.0
+        self.app['configuration']['2005'].union_fee = 1434.0
         error, payment = utils.setPaymentDetails('schoolfee',self.student)
-        self.assertEqual(error, u'Pay ICT fee(s) first.')
+        self.assertEqual(error, u'Pay Student Union and ICT fee(s) first.')
         error, payment = utils.setPaymentDetails('ict_entre',self.student)
         self.assertEqual(error, None)
@@ -80,4 +82,11 @@
         payment.p_state = 'paid'
         self.student['payments']['any_key'] = payment
+        error, payment = utils.setPaymentDetails('union',self.student)
+        self.assertEqual(error, None)
+        self.assertEqual(payment.p_level, 200)
+        self.assertEqual(payment.p_session, 2005)
+        self.assertEqual(payment.amount_auth, 1434.0)
+        payment.p_state = 'paid'
+        self.student['payments']['any_key_2'] = payment
         error, payment = utils.setPaymentDetails('schoolfee',self.student)
         self.assertEqual(error, None)
@@ -93,5 +102,12 @@
         self.assertEqual(payment.amount_auth, 4170.0)
         payment.p_state = 'paid'
-        self.student['payments']['any_key_2'] = payment
+        self.student['payments']['any_key_3'] = payment
+        error, payment = utils.setPaymentDetails('union',self.student)
+        self.assertEqual(error, None)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 1234.0)
+        payment.p_state = 'paid'
+        self.student['payments']['any_key_4'] = payment
         error, payment = utils.setPaymentDetails('schoolfee',self.student)
         self.assertEqual(error, None)
Index: /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py
===================================================================
--- /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py	(revision 17390)
+++ /main/kofacustom.edopoly/trunk/src/kofacustom/edopoly/students/utils.py	(revision 17391)
@@ -90,19 +90,19 @@
     def _requiredPaymentsMade(self, student, session):
         # SIWESS fee requirement removed on 18/01/2019
-        req_payments = ('ict_entre', 'logbook_combo')
-        req_payments_titles = 'ICT and Logbook'
+        req_payments = ('ict_entre', 'logbook_combo','union')
+        req_payments_titles = 'ICT, Student Union and Logbook'
         # All ND and HND part time do not pay for LOGBOOK
         if student.current_mode.endswith('_pt'):
-            req_payments = ('ict_entre',)
-            req_payments_titles = 'ICT'
+            req_payments = ('ict_entre', 'union')
+            req_payments_titles = 'Student Union and ICT'
         # HND1 and HND2 full time do not pay for LOGBOOK
         elif student.current_mode == 'hnd_ft' and student.state in (
             CLEARED, RETURNING):
-            req_payments = ('ict_entre',)
-            req_payments_titles = 'ICT'
+            req_payments = ('ict_entre', 'union')
+            req_payments_titles = 'Student Union and ICT'
         # ND2 FULL TIME do not pay LOGBOOK
         elif student.current_mode == 'nd_ft' and student.state == RETURNING:
-            req_payments = ('ict_entre',)
-            req_payments_titles = 'ICT'
+            req_payments = ('ict_entre', 'union')
+            req_payments_titles = 'Student Union and ICT'
         num = 0
         if len(student['payments']):
@@ -153,7 +153,7 @@
             p_level = student['studycourse'].current_level
             p_current = True
-        # The following three fees are part of the school fee which must be
+        # The following fout fees are part of the school fee which must be
         # paid before tuition fee. They are paid for next session.
-        if category in ('ict_entre', 'logbook_combo', 'siwess_combo') and \
+        if category in ('ict_entre', 'logbook_combo', 'siwess_combo', 'union') and \
             student.state == RETURNING and not previous_session:
             p_session, p_level = self.getReturningData(student)
