Changeset 9285


Ignore:
Timestamp:
4 Oct 2012, 09:32:39 (12 years ago)
Author:
Henrik Bettermann
Message:

Configure interswitch module for student payments.

Location:
main/waeup.futminna/trunk/src/waeup/futminna/interswitch
Files:
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.futminna/trunk/src/waeup/futminna/interswitch/browser.py

    r8957 r9285  
    2424from waeup.kofa.browser.layout import KofaPage, UtilityView
    2525from waeup.kofa.accesscodes import create_accesscode
    26 from waeup.kofa.interfaces import RETURNING, IKofaUtils
     26from waeup.kofa.interfaces import RETURNING, CLEARED, IKofaUtils
    2727from waeup.kofa.utils.helpers import to_timezone
    2828from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
     
    3333from waeup.futminna.interfaces import MessageFactory as _
    3434
    35 PRODUCT_ID = '57'
     35PRODUCT_ID = '117'
    3636SITE_NAME = 'futminna-kofa.waeup.org'
    37 PROVIDER_ACCT = '1010764827'
    38 PROVIDER_BANK_ID = '117'
     37PROVIDER_ACCT = '0061001000021095'
     38PROVIDER_BANK_ID = '89'
    3939PROVIDER_ITEM_NAME = 'BT Education'
    4040INSTITUTION_NAME = 'FUTMinna'
     
    136136        return self.view.url(self.view.context, self.target)
    137137
    138 class InterswitchActionButtonApplicant(APABApplicant):
    139     grok.order(1)
    140     grok.context(ICustomApplicantOnlinePayment)
    141     grok.require('waeup.payApplicant')
    142     icon = 'actionicon_pay.png'
    143     text = _('CollegePAY')
    144     target = 'goto_interswitch'
    145 
    146     @property
    147     def target_url(self):
    148         if self.context.p_state != 'unpaid':
    149             return ''
    150         return self.view.url(self.view.context, self.target)
    151 
    152 # Deprecated
    153 #class InterswitchRequestCallbackActionButtonStudent(RCABStudent):
    154 #    grok.order(3)
    155 #    grok.context(ICustomStudentOnlinePayment)
    156 #    icon = 'actionicon_call.png'
    157 #    text = _('Request CollegePAY callback')
    158 
    159 #    def target_url(self):
    160 #        if self.context.p_state == 'paid':
    161 #            return ''
    162 #        site_redirect_url = self.view.url(self.view.context, 'isw_callback')
    163 #        args = {
    164 #            'transRef':self.context.p_id,
    165 #            'prodID':PRODUCT_ID,
    166 #            'redirectURL':site_redirect_url}
    167 #        return QUERY_URL + '?%s' % urllib.urlencode(args)
    168 
    169 # Alternative preferred solution
    170138class InterswitchRequestWebserviceActionButtonStudent(APABStudent):
    171139    grok.order(2)
     
    175143    text = _('Requery CollegePAY')
    176144    target = 'request_webservice'
    177 
    178 class InterswitchRequestWebserviceActionButtonApplicant(APABApplicant):
    179     grok.order(2)
    180     grok.context(ICustomApplicantOnlinePayment)
    181     grok.require('waeup.payApplicant')
    182     icon = 'actionicon_call.png'
    183     text = _('Requery CollegePAY')
    184     target = 'request_webservice'
    185 
    186145
    187146class InterswitchPageStudent(KofaPage):
     
    229188        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
    230189        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
    231         if student.current_mode.endswith('_ft') \
    232             and student.state == RETURNING:
    233             provider_amt = 600
    234         else:
    235             provider_amt = 1500
     190        provider_amt = 1500
    236191        xmldict['provider_amt'] = 100 * provider_amt
     192
    237193        # Institution data
    238194        studycourse = student['studycourse']
     
    241197        xmldict['institution_acct'] = '000000000000'
    242198        xmldict['institution_bank_id'] = '00'
    243         xmldict['institution_amt'] = 100 * (self.context.amount_auth - provider_amt - 150)
     199        xmldict['institution_amt'] = 100 * (self.context.amount_auth - provider_amt - 300)
     200
     201        if self.context.student.current_mode in ('pg_ft'):
     202            pay_item_id = "11703"
     203        elif self.context.student.state == CLEARED and \
     204            self.context.student.current_level == 100:
     205            pay_item_id = "11700"
     206        elif self.context.student.state == CLEARED and \
     207            self.context.student.current_level == 200:
     208            pay_item_id = "11701"
     209        elif self.context.student.state == CLEARED and \
     210            self.context.student.current_level == 300:
     211            pay_item_id = "11702"
     212        elif self.context.student.state == RETURNING and \
     213            self.context.student.current_level in (100,110):
     214            pay_item_id = "11701"
     215        elif self.context.student.state == RETURNING and \
     216            self.context.student.current_level in (200,210):
     217            pay_item_id = "11702"
     218        elif self.context.student.state == RETURNING and \
     219            self.context.student.current_level in (300,310):
     220            pay_item_id = "11703"
     221        elif self.context.student.state == RETURNING and \
     222            self.context.student.current_level in (400,410,500,510,600):
     223            pay_item_id = "11704"
     224        else:
     225            pay_item_id = ""
     226
     227        if self.context.student.current_mode == 'jm_ft':
     228            xmldict['institution_acct'] = "000000000000"
     229            xmldict['institution_bank_id'] = '0'
     230        elif self.context.student.current_mode == 'pg_ft':
     231            xmldict['institution_acct'] = "2522040000134"
     232            xmldict['institution_bank_id'] = '8'
     233        elif self.context.student.state == CLEARED and \
     234            self.context.student.current_level == 100:
     235            xmldict['institution_acct'] = "0030001000017110"
     236            xmldict['institution_bank_id'] = '89'
     237        elif self.context.student.state == CLEARED and \
     238            self.context.student.current_level == 200:
     239            xmldict['institution_acct'] = "0591201005146"
     240            xmldict['institution_bank_id'] = '101'
     241        elif self.context.student.state == CLEARED and \
     242            self.context.student.current_level == 300:
     243            xmldict['institution_acct'] = "6013803345"
     244            xmldict['institution_bank_id'] = '117'
     245        elif self.context.student.state == RETURNING and \
     246            self.context.student.current_level in (100,110):
     247            xmldict['institution_acct'] = "0591201005146"
     248            xmldict['institution_bank_id'] = '101'
     249        elif self.context.student.current_level in (200,210):
     250            xmldict['institution_acct'] = "6013803345"
     251            xmldict['institution_bank_id'] = '117'
     252        elif self.context.student.current_level in (300,310):
     253            xmldict['institution_acct'] = "2522040000134"
     254            xmldict['institution_bank_id'] = '8'
     255        #Change of acct from UBA to GTBank
     256        elif self.context.student.current_level in (400,410,500,510,600):
     257            xmldict['institution_acct'] = "3713516838111"
     258            xmldict['institution_bank_id'] = '10'
     259
    244260        xmldict['institution_item_name'] = self.context.p_category
    245261        xmldict['institution_name'] = INSTITUTION_NAME
     
    254270        return
    255271
    256 class InterswitchPageApplicant(KofaPage):
    257     """ View which sends a POST request to the Interswitch
    258     CollegePAY payment gateway.
    259     """
    260     grok.context(ICustomApplicantOnlinePayment)
    261     grok.require('waeup.payApplicant')
    262     grok.template('applicant_goto_interswitch')
    263     grok.name('goto_interswitch')
    264     label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
    265     submit_button = _('Submit')
    266     action = POST_ACTION
    267     site_name = SITE_NAME
    268     currency = CURRENCY
    269     pay_item_id = '5703'
    270     product_id = PRODUCT_ID
    271 
    272     def update(self):
    273         if self.context.p_state != 'unpaid':
    274             self.flash(_("Payment ticket can't be re-send to CollegePAY."))
    275             self.redirect(self.url(self.context, '@@index'))
    276             return
    277         if self.context.__parent__.__parent__.expired \
    278             and self.context.__parent__.__parent__.strict_deadline:
    279             self.flash(_("Payment ticket can't be send to CollegePAY. "
    280                          "Application period has expired."))
    281             self.redirect(self.url(self.context, '@@index'))
    282             return
    283         self.applicant = self.context.__parent__
    284         self.amount_auth = 100 * self.context.amount_auth
    285         xmldict = {}
    286         self.category = payment_categories.getTermByToken(
    287             self.context.p_category).title
    288         tz = getUtility(IKofaUtils).tzinfo
    289         self.local_date_time = to_timezone(
    290             self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
    291         self.site_redirect_url = self.url(self.context, 'request_webservice')
    292         if self.applicant.applicant_id.startswith('pg'):
    293             provider_amt = 400
    294             xmldict['institution_acct'] = '0031716030'
    295             xmldict['institution_bank_id'] = '10'
    296         else:
    297             provider_amt = 250
    298             xmldict['institution_acct'] = '6220032503'
    299             xmldict['institution_bank_id'] = '51'
    300         xmldict['detail_ref'] = self.context.p_id
    301         xmldict['provider_amt'] = 100 * provider_amt
    302         xmldict['provider_acct'] = PROVIDER_ACCT
    303         xmldict['provider_bank_id'] = PROVIDER_BANK_ID
    304         xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
    305         xmldict['institution_amt'] = 100 * (self.context.amount_auth - provider_amt - 150)
    306         xmldict['institution_item_name'] = self.context.p_category
    307         xmldict['institution_name'] = INSTITUTION_NAME
    308         # Interswitch amount is not part of the xml data
    309         xmltext = """<payment_item_detail>
    310 <item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
    311 <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" />
    312 <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" />
    313 </item_details>
    314 </payment_item_detail>""" % xmldict
    315         self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
    316         return
    317 
    318 # Deprecated
    319 #class InterswitchPaymentCallbackPageStudent(UtilityView, grok.View):
    320 #    """ Callback view for the CollegePAY gateway
    321 #    """
    322 #    grok.context(ICustomStudentOnlinePayment)
    323 #    grok.name('isw_callback')
    324 #    grok.require('waeup.payStudent')
    325 
    326     # This view is not yet working for offline querying transactions
    327     # since the query string differs from the query string sent after
    328     # posting transactions. This Interswitch bug must be removed first.
    329     # Alternatively, we could use the webservice only and replace
    330     # the RequestCallbackActionButton by a RequestWebserviceActionButton
    331 
    332 #    def update(self):
    333 #        if self.context.p_state == 'paid':
    334 #            self.flash(_('This ticket has already been paid.'))
    335 #            return
    336 #        student = self.context.student
    337 #        query = self.request.form
    338 #        write_log_message(self,'callback received: %s' % query)
    339 #        self.context.r_card_num = query.get('cardNum', None)
    340 #        self.context.r_code = query.get('resp', None)
    341 #        self.context.r_pay_reference  = query.get('payRef', None)
    342 #        self.context.r_amount_approved = float(query.get('apprAmt', '0.0')) / 100
    343 #        self.context.r_desc = query.get('desc', None)
    344 #        if self.context.r_code != '00':
    345 #            self.flash(_('Unsuccessful callback: ${a}',
    346 #                mapping = {'a': query.get('desc', _('Incomplete query string.'))}))
    347 #            write_log_message(self,'unsuccessful callback: %s' % self.context.p_id)
    348 #            self.context.p_state = 'failed'
    349 #            return
    350 #        if self.context.r_amount_approved != payment.amount_auth:
    351 #            self.flash(_('Wrong amount'))
    352 #            write_log_message(
    353 #                self,'successful but wrong amount: %s' % self.context.p_id)
    354 #            self.context.p_state = 'failed'
    355 #            return
    356 #        try:
    357 #            validation_list = get_SOAP_response(
    358 #                PRODUCT_ID, self.context.p_id).split(':')
    359             # Validation does not make sense yet since the query string
    360             # formats are conflicting. We are only printing the validation
    361             # string, nothing else.
    362 #            print 'WARNING: Webservice validation is not yet implemented'
    363 #            print 'validation list: %s' % validation_list
    364 #        except:
    365 #            print 'Connection to webservice failed.'
    366         # Add webservice validation here
    367 #        write_log_message(self,'valid callback: %s' % self.context.p_id)
    368 #        self.context.p_state = 'paid'
    369 #        self.context.payment_date = datetime.utcnow()
    370 #        actions_after_student_payment(student, self.context, self)
    371 #        return
    372 
    373 #    def render(self):
    374 #        self.redirect(self.url(self.context, '@@index'))
    375 #        return
    376 
    377 # Alternative solution, replaces InterswitchPaymentCallbackPage
    378272class InterswitchPaymentRequestWebservicePageStudent(UtilityView, grok.View):
    379273    """ Request webservice view for the CollegePAY gateway
     
    403297        self.redirect(self.url(self.context, '@@index'))
    404298        return
    405 
    406 class InterswitchPaymentRequestWebservicePageApplicant(UtilityView, grok.View):
    407     """ Request webservice view for the CollegePAY gateway
    408     """
    409     grok.context(ICustomApplicantOnlinePayment)
    410     grok.name('request_webservice')
    411     grok.require('waeup.payApplicant')
    412 
    413     def update(self):
    414         if self.context.p_state == 'paid':
    415             self.flash(_('This ticket has already been paid.'))
    416             return
    417         applicant = self.context.__parent__
    418         success, msg, log = query_interswitch(self.context)
    419         applicant.writeLogMessage(self, log)
    420         if not success:
    421             self.flash(msg)
    422             return
    423         success, msg, log = self.context.doAfterApplicantPayment()
    424         if log is not None:
    425             applicant.writeLogMessage(self, log)
    426         self.flash(msg)
    427         return
    428 
    429     def render(self):
    430         self.redirect(self.url(self.context, '@@index'))
    431         return
  • main/waeup.futminna/trunk/src/waeup/futminna/interswitch/tests.py

    r9155 r9285  
    5151        self.browser.open(self.payments_path + '/addop')
    5252        self.browser.getControl("Create ticket").click()
    53         self.assertMatches('...Payment components not yet configured...',
     53        self.assertMatches('...Payment ticket created...',
    5454                           self.browser.contents)
    55 
    56 
    57 class InterswitchTestsApplicants(ApplicantsFullSetup):
    58     """Tests for the Interswitch payment gateway.
    59     """
    60 
    61     layer = FunctionalLayer
    62 
    63     def setUp(self):
    64         super(InterswitchTestsApplicants, self).setUp()
    65         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
    66         self.browser.open(self.manage_path)
    67         #IWorkflowState(self.student).setState('started')
    68         super(InterswitchTestsApplicants, self).fill_correct_values()
    69         self.applicantscontainer.application_fee = 1000.0
    70         self.browser.getControl(name="transition").value = ['start']
    71         self.browser.getControl("Save").click()
    72         self.browser.getControl("Add online").click()
    73         self.assertMatches('...ticket created...',
    74                            self.browser.contents)
    75         #ctrl = self.browser.getControl(name='val_id')
    76         #value = ctrl.options[0]
    77         #self.browser.getLink(value).click()
     55        ctrl = self.browser.getControl(name='val_id')
     56        value = ctrl.options[0]
     57        self.browser.getLink(value).click()
    7858        self.assertMatches('...Amount Authorized...',
    7959                           self.browser.contents)
    8060        self.assertMatches(
    81             '...<span>1000.0</span>...',
     61            '...<span>131500.0</span>...',
    8262            self.browser.contents)
    8363        self.payment_url = self.browser.url
    84 
    8564
    8665    def test_interswitch_form(self):
     
    9170                           self.browser.contents)
    9271        self.assertMatches(
    93             '...<input type="hidden" name="amount" value="100000.0" />...',
     72            '...<input type="hidden" name="amount" value="13150000.0" />...',
    9473            self.browser.contents)
    9574
    9675    @external_test
    9776    def test_webservice(self):
    98 
    9977        self.browser.open(self.payment_url + '/request_webservice')
    10078        self.assertMatches('...Unsuccessful callback...',
Note: See TracChangeset for help on using the changeset viewer.