Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9148)
@@ -55,5 +55,6 @@
     IStudentAccommodation, IStudentStudyLevel,
     ICourseTicket, ICourseTicketAdd, IStudentPaymentsContainer,
-    IStudentOnlinePayment, IBedTicket, IStudentsUtils, IStudentRequestPW
+    IStudentOnlinePayment, IStudentPreviousPayment,
+    IBedTicket, IStudentsUtils, IStudentRequestPW
     )
 from waeup.kofa.students.catalog import search
@@ -1213,4 +1214,6 @@
     def createTicket(self, **data):
         p_category = data['p_category']
+        previous_session = data.get('p_session', None)
+        previous_level = data.get('p_level', None)
         student = self.context.__parent__
         if p_category == 'bed_allocation' and student[
@@ -1223,7 +1226,11 @@
                 return
         students_utils = getUtility(IStudentsUtils)
-        error, payment = students_utils.setPaymentDetails(p_category, student)
+        error, payment = students_utils.setPaymentDetails(
+            p_category, student, previous_session, previous_level)
         if error is not None:
             self.flash(error)
+            if 'Would you like' in error:
+                self.redirect(self.url(self.context) + '/@@addpp')
+                return
             self.redirect(self.url(self.context))
             return
@@ -1232,4 +1239,15 @@
         self.redirect(self.url(self.context))
         return
+
+class PreviousPaymentAddFormPage(OnlinePaymentAddFormPage):
+    """ Page to add an online payment ticket for previous sessions
+    """
+    grok.context(IStudentPaymentsContainer)
+    grok.name('addpp')
+    grok.require('waeup.payStudent')
+    form_fields = grok.AutoFields(IStudentPreviousPayment).select(
+        'p_category', 'p_session', 'p_level')
+    label = _('Add previous session online payment')
+    pnav = 4
 
 class OnlinePaymentDisplayFormPage(KofaDisplayFormPage):
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 9148)
@@ -66,5 +66,6 @@
         """
 
-    def setPaymentDetails(category, student):
+    def setPaymentDetails(category, student, previous_session=None,
+            previous_level=None,):
         """Create Payment object and set the payment data of a student for
         the payment category specified.
@@ -560,4 +561,11 @@
     """
 
+    p_current = schema.Bool(
+        title = _(u'Current Session Payment'),
+        default = True,
+        required = False,
+        readonly = True,
+        )
+
     p_level = schema.Int(
         title = _(u'Payment Level'),
@@ -583,4 +591,21 @@
 IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
     'p_session'].order
+
+class IStudentPreviousPayment(IOnlinePayment):
+    """An interface for adding previous session payments.
+
+    """
+
+    p_session = schema.Choice(
+        title = _(u'Payment Session'),
+        source = academic_sessions_vocab,
+        required = True,
+        )
+
+    p_level = schema.Choice(
+        title = _(u'Payment Level'),
+        source = StudyLevelSource(),
+        required = True,
+        )
 
 class ICSVStudentExporter(ICSVExporter):
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/payments.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/payments.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/payments.py	(revision 9148)
@@ -97,7 +97,8 @@
         """Process student after payment was made.
         """
-        error = self._createActivationCodes()
-        if error is not None:
-            return False, error, error
+        if self.p_current:
+            error = self._createActivationCodes()
+            if error is not None:
+                return False, error, error
         log = 'successful payment: %s' % self.p_id
         msg = _('Successful payment')
@@ -107,7 +108,8 @@
         """Process student after payment was approved.
         """
-        error = self._createActivationCodes()
-        if error is not None:
-            return False, error, error
+        if self.p_current:
+            error = self._createActivationCodes()
+            if error is not None:
+                return False, error, error
         log = 'payment approved: %s' % self.p_id
         msg = _('Payment approved')
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9148)
@@ -1575,5 +1575,57 @@
         return
 
-    def test_postgraduate_payments(self):
+    def test_student_previous_payments(self):
+        # Login
+        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()
+
+        # Students can add previous school fee payment tickets in any state.
+        IWorkflowState(self.student).setState('courses registered')
+        self.browser.open(self.payments_path)
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['schoolfee']
+        self.browser.getControl("Create ticket").click()
+
+        # Amount cannot be determined since the state is not
+        # 'cleared' or 'returning'
+        self.assertMatches('...Amount could not be determined...',
+                           self.browser.contents)
+        self.assertMatches('...Would you like to pay for a previous session?...',
+                           self.browser.contents)
+
+        # Previous session payment form is provided
+        self.browser.getControl(name="form.p_category").value = ['schoolfee']
+        self.browser.getControl(name="form.p_session").value = ['2004']
+        self.browser.getControl(name="form.p_level").value = ['300']
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches('...ticket created...',
+                           self.browser.contents)
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[0]
+        self.browser.getLink(value).click()
+        self.assertMatches('...Amount Authorized...',
+                           self.browser.contents)
+        self.assertEqual(self.student['payments'][value].amount_auth, 20000.0)
+
+        # Payment session is properly set
+        self.assertEqual(self.student['payments'][value].p_session, 2004)
+        self.assertEqual(self.student['payments'][value].p_level, 300)
+
+        # We simulate the approval
+        self.browser.open(self.browser.url + '/fake_approve')
+        self.assertMatches('...Payment approved...',
+                          self.browser.contents)
+
+        # No AC has been created
+        self.assertEqual(len(self.app['accesscodes']['SFE-0'].keys()), 0)
+        self.assertTrue(self.student['payments'][value].ac is None)
+
+        # Current payment flag is set False
+        self.assertFalse(self.student['payments'][value].p_current)
+        return
+
+    def test_student_postgraduate_payments(self):
         self.certificate.study_mode = 'pg_ft'
         self.certificate.start_level = 999
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 9148)
@@ -371,9 +371,9 @@
         self.assertEqual(
             result,
-            'ac,amount_auth,creation_date,p_category,p_id,'
+            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
             'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
             'r_code,r_desc,student_id\r\n'
 
-            ',0.0,2012-04-01 13:12:01,schoolfee,,,,,unpaid,,0.0,,,\r\n'
+            ',0.0,2012-04-01 13:12:01,schoolfee,1,,,,,unpaid,,0.0,,,\r\n'
             )
         return
@@ -389,9 +389,9 @@
         self.assertEqual(
             result,
-            'ac,amount_auth,creation_date,p_category,p_id,'
+            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
             'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
             'r_code,r_desc,student_id\r\n'
 
-            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
+            '666,0.0,2012-04-01 13:12:01,schoolfee,1,my-id,'
             'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
             'r-code,,A111111\r\n'
@@ -408,9 +408,9 @@
         self.assertEqual(
             result,
-            'ac,amount_auth,creation_date,p_category,p_id,'
+            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
             'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
             'r_code,r_desc,student_id\r\n'
 
-            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
+            '666,0.0,2012-04-01 13:12:01,schoolfee,1,my-id,'
             'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
             'r-code,,A111111\r\n'
@@ -427,9 +427,9 @@
         self.assertEqual(
             result,
-            'ac,amount_auth,creation_date,p_category,p_id,'
+            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
             'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
             'r_code,r_desc,student_id\r\n'
 
-            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
+            '666,0.0,2012-04-01 13:12:01,schoolfee,1,my-id,'
             'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
             'r-code,,A111111\r\n'
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 9147)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 9148)
@@ -281,5 +281,6 @@
         return
 
-    def setPaymentDetails(self, category, student):
+    def setPaymentDetails(self, category, student,
+            previous_session=None, previous_level=None):
         """Create Payment object and set the payment data of a student for
         the payment category specified.
@@ -288,6 +289,12 @@
         p_item = u''
         amount = 0.0
-        p_session = student['studycourse'].current_session
-        p_level = student['studycourse'].current_level
+        if previous_session:
+            p_session = previous_session
+            p_level = previous_level
+            p_current = False
+        else:
+            p_session = student['studycourse'].current_session
+            p_level = student['studycourse'].current_level
+            p_current = True
         session = str(p_session)
         try:
@@ -301,17 +308,23 @@
             except (AttributeError, TypeError):
                 return _('Study course data are incomplete.'), None
-            if student.state == CLEARED:
-                amount = getattr(certificate, 'school_fee_1', 0.0)
-            elif student.state == RETURNING:
-                # In case of returning school fee payment the payment session
-                # and level contain the values of the session the student
-                # has paid for.
-                p_session, p_level = self.getReturningData(student)
-                amount = getattr(certificate, 'school_fee_2', 0.0)
-            elif student.is_postgrad and student.state == PAID:
-                # Returning postgraduate students also pay for the next session
-                # but their level always remains the same.
-                p_session += 1
-                amount = getattr(certificate, 'school_fee_2', 0.0)
+            if previous_session:
+                if previous_level == 100:
+                    amount = getattr(certificate, 'school_fee_1', 0.0)
+                else:
+                    amount = getattr(certificate, 'school_fee_2', 0.0)
+            else:
+                if student.state == CLEARED:
+                    amount = getattr(certificate, 'school_fee_1', 0.0)
+                elif student.state == RETURNING:
+                    # In case of returning school fee payment the payment session
+                    # and level contain the values of the session the student
+                    # has paid for.
+                    p_session, p_level = self.getReturningData(student)
+                    amount = getattr(certificate, 'school_fee_2', 0.0)
+                elif student.is_postgrad and student.state == PAID:
+                    # Returning postgraduate students also pay for the next session
+                    # but their level always remains the same.
+                    p_session += 1
+                    amount = getattr(certificate, 'school_fee_2', 0.0)
         elif category == 'clearance':
             p_item = student['studycourse'].certificate.code
@@ -321,5 +334,6 @@
             amount = academic_session.booking_fee
         if amount in (0.0, None):
-            return _(u'Amount could not be determined.'), None
+            return _('Amount could not be determined.' +
+                     ' Would you like to pay for a previous session?'), None
         for key in student['payments'].keys():
             ticket = student['payments'][key]
@@ -328,5 +342,6 @@
                ticket.p_item == p_item and \
                ticket.p_session == p_session:
-                  return _('This type of payment has already been made.'), None
+                  return _('This type of payment has already been made.' +
+                           ' Would you like to pay for a previous session?'), None
         payment = createObject(u'waeup.StudentOnlinePayment')
         timestamp = ("%d" % int(time()*10000))[1:]
@@ -336,4 +351,5 @@
         payment.p_session = p_session
         payment.p_level = p_level
+        payment.p_current = p_current
         payment.amount_auth = amount
         return None, payment
@@ -358,5 +374,7 @@
             return
         end_level = certificate.end_level
-        if entry_session == grok.getSite()['hostels'].accommodation_session:
+        if current_level == 10:
+            bt = 'pr'
+        elif entry_session == grok.getSite()['hostels'].accommodation_session:
             bt = 'fr'
         elif current_level >= end_level:
