Index: main/waeup.kwarapoly/trunk/CHANGES.txt
===================================================================
--- main/waeup.kwarapoly/trunk/CHANGES.txt	(revision 11622)
+++ main/waeup.kwarapoly/trunk/CHANGES.txt	(revision 11623)
@@ -4,4 +4,8 @@
 1.2dev (unreleased)
 ===================
+
+* Fees are required and must not be set to None.
+
+* Session specific penalty fees added before re-categorization of carryover fees.
 
 * Webservice test extended to ensure that special payment applicants
Index: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interfaces.py
===================================================================
--- main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interfaces.py	(revision 11622)
+++ main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interfaces.py	(revision 11623)
@@ -35,5 +35,5 @@
         title = _(u'School Fee (ignored)'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -41,5 +41,5 @@
         title = _(u'Application Fee (fallback)'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -47,5 +47,5 @@
         title = _(u'Clearance Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -53,5 +53,5 @@
         title = _(u'Booking Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -61,5 +61,5 @@
         title = _(u'Maintenance Fee (fallback)'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -67,5 +67,5 @@
         title = _(u'Gown Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -73,5 +73,5 @@
         title = _(u'Transfer Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -79,90 +79,90 @@
         title = _(u' Certificate Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     state_result_fee = schema.Float(
         title = _(u'Statement of Result Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     transcript_local_fee = schema.Float(
         title = _(u'Transcript (local) Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     transcript_foreign_fee = schema.Float(
         title = _(u'Transcript (foreign) Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     ver_result_fee = schema.Float(
         title = _(u'Verification of Result Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     change_course_fee = schema.Float(
         title = _(u'Change of Course Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     change_inst_fee = schema.Float(
         title = _(u'Change of Institute Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     jamb_reject_fee = schema.Float(
         title = _(u'JAMB Rejection Form Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     cert_of_cert_fee = schema.Float(
         title = _(u'Certification of Certificate Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     ref_let_fee = schema.Float(
         title = _(u'Recommendation/Reference Letter Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     proc_cert_fee = schema.Float(
         title = _(u'Processing of Certificate by Proxy Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     loss_idcard_fee = schema.Float(
         title = _(u'Loss of ID Card Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     loss_examcard_fee = schema.Float(
         title = _(u'Loss of Exam Card Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     loss_result_fee = schema.Float(
         title = _(u'Loss of Result Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     loss_receipt_fee = schema.Float(
         title = _(u'Loss of Receipt Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     loss_clearance_fee = schema.Float(
         title = _(u'Loss of Clearance Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     conv_brochure_fee = schema.Float(
         title = _(u'Convocation Brochure Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
     penalty_ug = schema.Float(
         title = _(u'UG Penalty Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
@@ -170,5 +170,5 @@
         title = _(u'PG Penalty Fee'),
         default = 0.0,
-        required = False,
+        required = True,
         )
 
Index: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py
===================================================================
--- main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py	(revision 11622)
+++ main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/utils.py	(revision 11623)
@@ -258,4 +258,10 @@
                ticket.p_session == p_session:
                   return _('This type of payment has already been made.'), None
+        # Add session specific penalty fee.
+        if category == 'schoolfee' and student.is_postgrad:
+            amount += academic_session.penalty_pg
+        elif category == 'schoolfee':
+            amount += academic_session.penalty_ug
+        # Recategorize carryover fees.
         if category.startswith('carryover'):
             p_item = getUtility(IKofaUtils).PAYMENT_CATEGORIES[category]
@@ -263,9 +269,4 @@
             # Now we change the category to reduce the number of categories.
             category = 'schoolfee'
-        # Add session specific penalty fee.
-        if category == 'schoolfee' and student.is_postgrad:
-            amount += academic_session.penalty_pg
-        elif category == 'schoolfee':
-            amount += academic_session.penalty_ug
         if self._isPaymentDisabled(p_session, category, student):
             return _('Payment temporarily disabled.'), None
