Index: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/browser.py
===================================================================
--- main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/browser.py	(revision 9751)
+++ main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/browser.py	(revision 9789)
@@ -21,10 +21,10 @@
 from zope.interface import Interface
 from zope.component import getUtility, queryAdapter
-from kofacustom.nigeria.interswitch.helpers import query_interswitch
+from kofacustom.nigeria.interswitch.browser import (
+    InterswitchPaymentRequestWebservicePageStudent
+    )
 from waeup.kofa.browser.layout import KofaPage, UtilityView
 from waeup.kofa.interfaces import IKofaUtils
 from waeup.kofa.utils.helpers import to_timezone
-from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
-from waeup.kofa.applicants.viewlets import ApprovePaymentActionButton as APABApplicant
 from waeup.kwarapoly.students.interfaces import ICustomStudentOnlinePayment
 from waeup.kwarapoly.applicants.interfaces import ICustomApplicantOnlinePayment
@@ -38,4 +38,5 @@
 INSTITUTION_NAME = 'KwaraPoly'
 CURRENCY = '566'
+GATEWAY_AMT = 300.0
 #QUERY_URL = 'https://webpay.interswitchng.com/paydirect/services/TransactionQueryURL.aspx'
 #QUERY_URL = 'https://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryURL.aspx'
@@ -58,48 +59,4 @@
             view.request, Interface, name='waeup.kwarapoly.interswitch')
     return static['interswitch_verve_mastercard.gif']()
-
-class InterswitchActionButtonStudent(APABStudent):
-    grok.order(1)
-    grok.context(ICustomStudentOnlinePayment)
-    grok.require('waeup.payStudent')
-    icon = 'actionicon_pay.png'
-    text = _('CollegePAY')
-    target = 'goto_interswitch'
-
-    @property
-    def target_url(self):
-        if self.context.p_state != 'unpaid':
-            return ''
-        return self.view.url(self.view.context, self.target)
-
-class InterswitchActionButtonApplicant(APABApplicant):
-    grok.order(1)
-    grok.context(ICustomApplicantOnlinePayment)
-    grok.require('waeup.payApplicant')
-    icon = 'actionicon_pay.png'
-    text = _('CollegePAY')
-    target = 'goto_interswitch'
-
-    @property
-    def target_url(self):
-        if self.context.p_state != 'unpaid':
-            return ''
-        return self.view.url(self.view.context, self.target)
-
-class InterswitchRequestWebserviceActionButtonStudent(APABStudent):
-    grok.order(2)
-    grok.context(ICustomStudentOnlinePayment)
-    grok.require('waeup.payStudent')
-    icon = 'actionicon_call.png'
-    text = _('Requery CollegePAY')
-    target = 'request_webservice'
-
-class InterswitchRequestWebserviceActionButtonApplicant(APABApplicant):
-    grok.order(2)
-    grok.context(ICustomApplicantOnlinePayment)
-    grok.require('waeup.payApplicant')
-    icon = 'actionicon_call.png'
-    text = _('Requery CollegePAY')
-    target = 'request_webservice'
 
 class InterswitchPageStudent(KofaPage):
@@ -149,5 +106,4 @@
         xmldict['provider_bank_id'] = PROVIDER_BANK_ID
         xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
-        xmldict['provider_amt'] = 100 * 1200
         # Institution data
         xmldict['institution_acct'] = "0000000000000"
@@ -155,11 +111,14 @@
         xmldict['institution_item_name'] = self.category
         xmldict['institution_name'] = INSTITUTION_NAME
-        xmldict['institution_amt'] = 100 * (self.context.amount_auth -300)
-        xmldict['dalash_amt'] = 0
         self.pay_item_id = '000'
         if self.context.p_category == 'schoolfee':
+            provider_amt = 1200.0
+            xmldict['provider_amt'] = 100 * provider_amt
             self.pay_item_id = '101'
-            # Dalash data
-            xmldict['dalash_amt'] = 100 * 1800
+            dalash_amt = 1800.0
+            xmldict['dalash_amt'] = 100 * dalash_amt
+            xmldict['institution_amt'] = 100 * (
+                self.context.amount_auth - provider_amt -
+                GATEWAY_AMT - dalash_amt)
             if xmldict['faculty'] in ('CPGS',):
                 xmldict['institution_acct'] = "1771180233"
@@ -178,6 +137,4 @@
                 xmldict['institution_acct'] = "2013910271"
                 xmldict['institution_bank_id'] = '8'
-            xmldict['institution_amt'] = 100 * (
-                self.context.amount_auth - 1200 - 300 - 1800)
 
         elif 'maintenance' in self.context.p_category:
@@ -185,4 +142,8 @@
             xmldict['institution_acct'] = "0039050937"
             xmldict['institution_bank_id'] = '31'
+            xmldict['institution_amt'] = 100 * (
+                self.context.amount_auth - GATEWAY_AMT)
+            dalash_amt = 0.0
+            provider_amt = 0.0
 
         hashargs = (
@@ -197,9 +158,9 @@
         # Interswitch amount is not part of the xml data
 
-        if self.context.p_category in ('schoolfee', 'co1', 'co2', 'co3'):
+        if self.context.p_category == 'schoolfee':
             xmltext = """<payment_item_detail>
 <item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
 <item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
-<item_detail item_id="2" item_name="Dalash" item_amt="%(dalash_amt)s" bank_id="117" acct_num="1013196791" />
+<item_detail item_id="2" item_name="Dalash" item_amt="%(dalash_amt)d" bank_id="117" acct_num="1013196791" />
 <item_detail item_id="3" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
 </item_details>
@@ -214,120 +175,15 @@
 
         self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
+        self.context.provider_amt = provider_amt
+        self.context.gateway_amt = GATEWAY_AMT
+        self.context.thirdparty_amt = dalash_amt
         return
 
-class InterswitchPageApplicant(KofaPage):
-    """ View which sends a POST request to the Interswitch
-    CollegePAY payment gateway.
-    """
-    grok.context(ICustomApplicantOnlinePayment)
-    grok.require('waeup.payApplicant')
-    grok.template('applicant_goto_interswitch')
-    grok.name('goto_interswitch')
-    label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
-    submit_button = _('Submit')
-    action = POST_ACTION
-    site_name = SITE_NAME
-    currency = CURRENCY
-    pay_item_id = ''
-    product_id = PRODUCT_ID
-
-    def interswitch_img_url(self):
-        return interswitch_img_url(self)
-
-    def update(self):
-        if self.context.p_state != 'unpaid':
-            self.flash(_("Payment ticket can't be re-send to CollegePAY."))
-            self.redirect(self.url(self.context, '@@index'))
-            return
-        if self.context.__parent__.__parent__.expired \
-            and self.context.__parent__.__parent__.strict_deadline:
-            self.flash(_("Payment ticket can't be send to CollegePAY. "
-                         "Application period has expired."))
-            self.redirect(self.url(self.context, '@@index'))
-            return
-        self.applicant = self.context.__parent__
-        self.amount_auth = 100 * self.context.amount_auth
-        xmldict = {}
-        self.category = getUtility(IKofaUtils).PAYMENT_CATEGORIES[self.context.p_category]
-        tz = getUtility(IKofaUtils).tzinfo
-        self.local_date_time = to_timezone(
-            self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
-        self.site_redirect_url = self.url(self.context, 'request_webservice')
-        xmldict['detail_ref'] = self.context.p_id
-        # Provider data
-        xmldict['provider_amt'] = 100 * 500
-        xmldict['provider_acct'] = PROVIDER_ACCT
-        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
-        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
-        # Institution data
-        xmldict['institution_amt'] = 100 * (self.context.amount_auth - 500 - 150)
-        xmldict['institution_acct'] = '0'
-        xmldict['institution_bank_id'] = '0'
-        xmldict['institution_item_name'] = self.context.p_category
-        xmldict['institution_name'] = INSTITUTION_NAME
-        # Interswitch amount is not part of the xml data
-        xmltext = """<payment_item_detail>
-<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
-<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
-<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
-</item_details>
-</payment_item_detail>""" % xmldict
-        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
-        return
-
-
-class InterswitchPaymentRequestWebservicePageStudent(UtilityView, grok.View):
+class InterswitchPaymentRequestWebservicePageStudent(
+    InterswitchPaymentRequestWebservicePageStudent):
     """ Request webservice view for the CollegePAY gateway
     """
     grok.context(ICustomStudentOnlinePayment)
-    grok.name('request_webservice')
-    grok.require('waeup.payStudent')
-
-    def update(self):
-        if self.context.p_state == 'paid':
-            self.flash(_('This ticket has already been paid.'))
-            return
-        student = self.context.student
-        success, msg, log = query_interswitch(
-            self.context, PRODUCT_ID, HOST, URL)
-        student.writeLogMessage(self, log)
-        if not success:
-            self.flash(msg)
-            return
-        success, msg, log = self.context.doAfterStudentPayment()
-        if log is not None:
-            student.writeLogMessage(self, log)
-        self.flash(msg)
-        return
-
-    def render(self):
-        self.redirect(self.url(self.context, '@@index'))
-        return
-
-class InterswitchPaymentRequestWebservicePageApplicant(UtilityView, grok.View):
-    """ Request webservice view for the CollegePAY gateway
-    """
-    grok.context(ICustomApplicantOnlinePayment)
-    grok.name('request_webservice')
-    grok.require('waeup.payApplicant')
-
-    def update(self):
-        if self.context.p_state == 'paid':
-            self.flash(_('This ticket has already been paid.'))
-            return
-        applicant = self.context.__parent__
-        success, msg, log = query_interswitch(
-            self.context, PRODUCT_ID, HOST, URL)
-        applicant.writeLogMessage(self, log)
-        if not success:
-            self.flash(msg)
-            return
-        success, msg, log = self.context.doAfterApplicantPayment()
-        if log is not None:
-            applicant.writeLogMessage(self, log)
-        self.flash(msg)
-        return
-
-    def render(self):
-        self.redirect(self.url(self.context, '@@index'))
-        return
+    product_id = PRODUCT_ID
+    gateway_host = HOST
+    gateway_url = URL
Index: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/tests.py
===================================================================
--- main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/tests.py	(revision 9751)
+++ main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/tests.py	(revision 9789)
@@ -16,4 +16,5 @@
 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##
+import os
 import grok
 from hurry.workflow.interfaces import IWorkflowState
@@ -31,5 +32,5 @@
 #   If you enable this, please make sure the external services
 #   do exist really and are not bothered by being spammed by a test programme.
-EXTERNAL_TESTS = False
+EXTERNAL_TESTS = True
 
 def external_test(func):
@@ -84,6 +85,6 @@
                            self.browser.contents)
         ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[0]
-        self.browser.getLink(value).click()
+        self.value = ctrl.options[0]
+        self.browser.getLink(self.value).click()
         self.assertMatches('...Amount Authorized...',
                            self.browser.contents)
@@ -107,5 +108,12 @@
     def test_interswitch_form(self):
         # Manager can access InterswitchForm
+        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
+        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
+        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
         self.browser.getLink("CollegePAY", index=0).click()
+        # Split amounts have been set.
+        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
+        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
+        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
         self.assertMatches('...Total Amount Authorized:...',
                            self.browser.contents)
@@ -162,4 +170,8 @@
         # Manager can access InterswitchForm
         self.browser.getLink("CollegePAY", index=0).click()
+        # Split amounts have been set.
+        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
+        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
+        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
         # The total amount to be processed by Interswitch
         # has been reduced by the Interswitch fee of 150 Nairas
@@ -188,4 +200,8 @@
         # Manager can access InterswitchForm
         self.browser.getLink("CollegePAY", index=0).click()
+        # Split amounts have been set.
+        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
+        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
+        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
         self.assertMatches('...<input type="hidden" name="pay_item_id" value="101" />...',
                            self.browser.contents)
@@ -204,29 +220,11 @@
             '...item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"...',
             self.browser.contents)
-
-#    @external_test
-#    def test_callback(self):
-
-        # Manager can call callback manually
-#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
-#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
-#                          self.browser.contents)
-#        self.assertMatches('...Failed...',
-#                           self.browser.contents)
-#        self.browser.open(self.payment_url + '/isw_callback')
-#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
-#                          self.browser.contents)
-#        self.assertMatches('...Failed...',
-#                           self.browser.contents)
-#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
-#        self.assertMatches('...Wrong amount...',
-#                          self.browser.contents)
-#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
-#        self.assertMatches('...Valid callback received...',
-#                          self.browser.contents)
 
     @external_test
     def test_webservice(self):
-
+        # First we have open InterswitchPageStudent to set provider_amt
+        # and gateway_amt
+        self.browser.open(self.payment_url + '/goto_interswitch')
+        # Now we can call the webservice
         self.browser.open(self.payment_url + '/request_webservice')
         self.assertMatches('...Unsuccessful callback...',
@@ -242,51 +240,47 @@
         self.assertEqual(results[0].p_state, 'failed')
 
-class InterswitchTestsApplicants(ApplicantsFullSetup):
-    """Tests for the Interswitch payment gateway.
-    """
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(InterswitchTestsApplicants, self).setUp()
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.manage_path)
-        #IWorkflowState(self.student).setState('started')
-        super(InterswitchTestsApplicants, self).fill_correct_values()
-        self.applicantscontainer.application_fee = 1000.0
-        self.browser.getControl(name="form.nationality").value = ['NG']
-        self.browser.getControl(name="transition").value = ['start']
-        self.browser.getControl("Save").click()
-        self.browser.getControl("Add online").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.assertMatches(
-            '...<span>1000.0</span>...',
-            self.browser.contents)
-        self.payment_url = self.browser.url
-
-
-    def test_interswitch_form(self):
-
-        # Manager can access InterswitchForm
-        self.browser.getLink("CollegePAY", index=0).click()
-        self.assertMatches('...Total Amount Authorized:...',
-                           self.browser.contents)
-        self.assertMatches(
-            '...<input type="hidden" name="amount" value="100000.0" />...',
-            self.browser.contents)
-
-    @external_test
-    def test_webservice(self):
-
+        # Let's replace the p_id with a valid p_id of the Kwarapoly
+        # live system. This is definitely not an appropriate
+        # solution for testing, but we have no choice since
+        # Interswitch doesn't provide any interface
+        # for testing.
+        payment = self.student['payments'][self.value]
+        payment.p_id = 'p3543612043224'
         self.browser.open(self.payment_url + '/request_webservice')
-        self.assertMatches('...Unsuccessful callback...',
-                          self.browser.contents)
-        # The payment is now in state failed
+        self.assertMatches('...Callback amount does not match...',
+                          self.browser.contents)
+        # The payment is now in state failed ...
         self.assertMatches('...<span>Failed</span>...',
                           self.browser.contents)
+        # Let's replace the amount autorized with the amount of the
+        # live system payment
+        payment.amount_auth = payment.r_amount_approved
+        self.browser.open(self.payment_url + '/request_webservice')
+        self.assertMatches('...Successful payment...',
+                          self.browser.contents)
+        # The payment is now in state paid ...
+        self.assertMatches('...<span>Paid</span>...',
+                          self.browser.contents)
+        # ... and the catalog has been updated
+        cat = getUtility(ICatalog, name='payments_catalog')
+        results = list(
+            cat.searchResults(p_state=('paid', 'paid')))
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0].p_state, 'paid')
+        # Approval is logged in students.log ...
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'students.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'zope.mgr - '
+            'waeup.kwarapoly.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
+            'W1000000 - successful schoolfee payment: p3543612043224\n'
+            in logcontent)
+        # ... and in payments.log
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'payments.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
+            '52100.0,00,1200.0,300.0,1800.0,,,\n'
+            in logcontent)
Index: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/browser.py
===================================================================
--- main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/browser.py	(revision 9751)
+++ main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/browser.py	(revision 9789)
@@ -36,5 +36,6 @@
     """
     grok.context(ICustomStudentOnlinePayment)
-    form_fields = grok.AutoFields(ICustomStudentOnlinePayment)
+    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
+        'provider_amt', 'gateway_amt', 'thirdparty_amt')
     form_fields[
         'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
@@ -52,5 +53,6 @@
     """
     grok.context(ICustomStudentOnlinePayment)
-    form_fields = grok.AutoFields(ICustomStudentOnlinePayment)
+    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
+        'provider_amt', 'gateway_amt', 'thirdparty_amt')
     form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
     form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
