Ignore:
Timestamp:
6 Nov 2019, 16:49:15 (5 years ago)
Author:
Henrik Bettermann
Message:

Remove and replace old Etranzact stuff.The module must be newly configured.

Location:
main/waeup.aaue/trunk/src/waeup/aaue/etranzact
Files:
2 deleted
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.aaue/trunk/src/waeup/aaue/etranzact/browser.py

    r15346 r15759  
    11## $Id$
    22##
    3 ## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
     3## Copyright (C) 2017 Uli Fouquet & Henrik Bettermann
    44## This program is free software; you can redistribute it and/or modify
    55## it under the terms of the GNU General Public License as published by
     
    1616## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    1717##
    18 from datetime import datetime
    19 import httplib
    20 import urllib
    21 import urllib2
    22 import re
    23 from xml.dom.minidom import parseString
    24 import grok
    25 from zope.component import getUtility
    26 from zope.catalog.interfaces import ICatalog
    27 from waeup.kofa.interfaces import IUniversity, CLEARED
    28 from waeup.kofa.payments.interfaces import IPayer
    29 from waeup.kofa.webservices import PaymentDataWebservice
    30 from waeup.kofa.browser.layout import KofaPage, UtilityView
    31 from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
    32 from waeup.kofa.applicants.viewlets import ApprovePaymentActionButton as APABApplicant
    33 from waeup.aaue.interfaces import academic_sessions_vocab
    34 from kofacustom.nigeria.interswitch.browser import (
    35     InterswitchActionButtonStudent,
    36     InterswitchRequestWebserviceActionButtonStudent,
    37     InterswitchActionButtonApplicant,
    38     InterswitchRequestWebserviceActionButtonApplicant)
    39 from waeup.aaue.interfaces import MessageFactory as _
    40 from waeup.aaue.students.interfaces import ICustomStudentOnlinePayment
    41 from waeup.aaue.applicants.interfaces import ICustomApplicantOnlinePayment
    4218
    43 ERROR_PART1 = (
    44         'PayeeName=N/A~'
    45         + 'Faculty=N/A~'
    46         + 'Department=N/A~'
    47         + 'Level=N/A~'
    48         + 'ProgrammeType=N/A~'
    49         + 'StudyType=N/A~'
    50         + 'Session=N/A~'
    51         + 'PayeeID=N/A~'
    52         + 'Amount=N/A~'
    53         + 'FeeStatus=')
    54 ERROR_PART2 = (
    55         '~Semester=N/A~'
    56         + 'PaymentType=N/A~'
    57         + 'MatricNumber=N/A~'
    58         + 'Email=N/A~'
    59         + 'PhoneNumber=N/A')
     19from kofacustom.nigeria.etranzact.applicantsbrowser import (
     20    EtranzactPageApplicant, EtranzactReceiveResponseApplicant,
     21    EtranzactRequestPaymentStatusPageApplicant)
     22from kofacustom.nigeria.etranzact.studentsbrowser import (
     23    EtranzactPageStudent, EtranzactReceiveResponseStudent,
     24    EtranzactRequestPaymentStatusPageStudent)
     25from kofacustom.nigeria.etranzact.payoutletbrowser import (
     26    EtranzactEnterPinPageStudent, EtranzactEnterPinPageApplicant,
     27    EtranzactQueryHistoryPageStudent, EtranzactQueryHistoryPageApplicant)
     28from kofacustom.nigeria.etranzact.payoutletwebservice  import NigeriaPaymentDataWebservice
    6029
    61 class CustomPaymentDataWebservice(PaymentDataWebservice):
     30# Temporarily we can use the test portal like in kofacustom.nigeria
     31
     32from kofacustom.nigeria.etranzact.tests import (
     33    HOST, HTTPS, SECRET_KEY, TERMINAL_ID, GATEWAY_AMT)
     34
     35#HOST = 'www.etranzact.net'
     36#HTTPS = True
     37#SECRET_KEY =
     38#TERMINAL_ID = 0570000070
     39#GATEWAY_AMT =
     40LOGO_URL = 'https://iuokada.waeup.org/static_custom/iou_logo.png'
     41
     42class CustomEtranzactPageApplicant(EtranzactPageApplicant):
     43
     44    host = HOST
     45    https = HTTPS
     46    secret_key = SECRET_KEY
     47    terminal_id = TERMINAL_ID
     48    logo_url = LOGO_URL
     49    gateway_amt = GATEWAY_AMT
     50
     51    def update(self):
     52        # Already now it becomes an Etranzact payment. We set the net amount
     53        # and add the gateway amount.
     54        if not self.context.r_company:
     55            self.context.net_amt = self.context.amount_auth
     56            self.context.amount_auth += self.gateway_amt
     57            self.context.gateway_amt = self.gateway_amt
     58            self.context.r_company = u'etranzact'
     59        self.amount = "%.1f" % self.context.amount_auth
     60        error = self.init_update()
     61        if error:
     62            self.flash(error, type='danger')
     63            self.redirect(self.url(self.context, '@@index'))
     64            return
     65        return
     66
     67class CustomEtranzactReceiveResponseApplicant(EtranzactReceiveResponseApplicant):
     68
     69    secret_key = SECRET_KEY
     70    terminal_id = TERMINAL_ID
     71
     72class CustomEtranzactRequestPaymentStatusPageApplicant(
     73    EtranzactRequestPaymentStatusPageApplicant):
     74
     75    host = HOST
     76    https = HTTPS
     77    secret_key = SECRET_KEY
     78    terminal_id = TERMINAL_ID
     79    logo_url = LOGO_URL
     80
     81class CustomEtranzactPageStudent(EtranzactPageStudent):
     82
     83    host = HOST
     84    https = HTTPS
     85    secret_key = SECRET_KEY
     86    terminal_id = TERMINAL_ID
     87    logo_url = LOGO_URL
     88    gateway_amt = GATEWAY_AMT
     89
     90    def update(self):
     91        # Already now it becomes an Etranzact payment. We set the net amount
     92        # and add the gateway amount.
     93        if not self.context.r_company:
     94            self.context.net_amt = self.context.amount_auth
     95            self.context.amount_auth += self.gateway_amt
     96            self.context.gateway_amt = self.gateway_amt
     97            self.context.r_company = u'etranzact'
     98        self.amount = "%.1f" % self.context.amount_auth
     99        error = self.init_update()
     100        if error:
     101            self.flash(error, type='danger')
     102            self.redirect(self.url(self.context, '@@index'))
     103            return
     104        return
     105
     106class CustomEtranzactReceiveResponseStudent(EtranzactReceiveResponseStudent):
     107
     108    secret_key = SECRET_KEY
     109    terminal_id = TERMINAL_ID
     110
     111class CustomEtranzactRequestPaymentStatusPageStudent(
     112    EtranzactRequestPaymentStatusPageStudent):
     113
     114    host = HOST
     115    https = HTTPS
     116    secret_key = SECRET_KEY
     117    terminal_id = TERMINAL_ID
     118    logo_url = LOGO_URL
     119
     120# Payoutlet customizations
     121
     122class CustomEtranzactEnterPinPageStudent(EtranzactEnterPinPageStudent):
     123    """Enter confirmation PIN and submit to `EtranzactQueryHistoryPageStudent`
     124    """
     125    gateway_amt = GATEWAY_AMT
     126
     127class CustomEtranzactEnterPinPageApplicant(EtranzactEnterPinPageApplicant):
     128    """Enter confirmation PIN and submit to `EtranzactQueryHistoryPageApplicant`
     129    """
     130    gateway_amt = GATEWAY_AMT
     131
     132class CustomEtranzactQueryHistoryPageStudent(EtranzactQueryHistoryPageStudent):
     133    """ Query history of Etranzact payments
     134    """
     135    terminal_id = TERMINAL_ID
     136    host = HOST
     137    https = HTTPS
     138
     139class CustomEtranzactQueryHistoryPageApplicant(EtranzactQueryHistoryPageApplicant):
     140    """ Query history of Etranzact payments
     141    """
     142    terminal_id = TERMINAL_ID
     143    host = HOST
     144    https = HTTPS
     145
     146class CustomPaymentDataWebservice(NigeriaPaymentDataWebservice):
    62147    """A simple webservice to publish payment and payer details on request from
    63148    accepted IP addresses without authentication.
    64 
    65     Etranzact is asking for the PAYEE_ID which is indeed misleading.
    66     These are not the data of the payee but of the payer. And it's
    67     not the id of the payer but of the payment.
    68149    """
    69     grok.name('feerequest')
    70 
    71150    #ACCEPTED_IP = ('195.219.3.181', '195.219.3.184')
    72151    ACCEPTED_IP = None
    73152
    74     def update(self, PAYEE_ID=None, PAYMENT_TYPE=None):
     153    CATEGORY_MAPPING = {
     154        'SCHOOLFEE': ('schoolfee',),
     155         }
    75156
    76         # webservice disabled on 6/3/19
    77         self.output = None
    78         return
    79 
    80         if PAYEE_ID == None:
    81             self.output = ERROR_PART1 + 'Missing PAYEE_ID' + ERROR_PART2
    82             return
    83         real_ip = self.request.get('HTTP_X_FORWARDED_FOR', None)
    84         # We can forego the logging once eTranzact payments run smoothly
    85         # and the accepted IP addresses are used.
    86         if real_ip:
    87             self.context.logger.info('PaymentDataWebservice called: %s' % real_ip)
    88         if real_ip  and self.ACCEPTED_IP:
    89             if real_ip not in  self.ACCEPTED_IP:
    90                 self.output = ERROR_PART1 + 'Wrong IP address' + ERROR_PART2
    91                 return
    92         category_mapping = {
    93             'SCHOOL-FEE-NEW': ('schoolfee',),
    94             'SCHOOL-FEE-RETURNING': ('schoolfee',),
    95             'SCHOOL-FEE-PLUS-NEW': ('schoolfee_incl',),
    96             'SCHOOL-FEE-PLUS-RETURNING': ('schoolfee_incl',),
    97             'SCHOOL-FEE-PG-NEW': ('schoolfee',),
    98             'SCHOOL-FEE-PG-RETURNING': ('schoolfee',),
    99             'SCHOOL-FEE-FIRST-INSTALMENT-PLUS': ('schoolfee_1',),
    100             'SCHOOL-FEE-SECOND-INSTALMENT': ('schoolfee_2',),
    101             'SCHOOL-FEE-BALANCE': ('schoolfee','schoolfee_incl',
    102                                    'schoolfee_1','schoolfee_2'),
    103             'SCHOOL-FEE-PT-NEW': ('schoolfee',),
    104             'SCHOOL-FEE-PT-RETURNING': ('schoolfee',),
    105             'SCHOOL-FEE-PT-PLUS-NEW': ('schoolfee_incl',),
    106             'SCHOOL-FEE-PT-PLUS-RETURNING': ('schoolfee_incl',),
    107             'SCHOOL-FEE-PT-PG-NEW': ('schoolfee',),
    108             'SCHOOL-FEE-PT-PG-RETURNING': ('schoolfee',),
    109             'SCHOOL-FEE-PT-FIRST-INSTALMENT-PLUS': ('schoolfee_1',),
    110             'SCHOOL-FEE-PT-SECOND-INSTALMENT': ('schoolfee_2',),
    111             'SCHOOL-FEE-PT-BALANCE': ('schoolfee','schoolfee_incl',
    112                                       'schoolfee_1','schoolfee_2'),
    113             'SCHOOL-FEE-FP-NEW': ('schoolfee',),
    114             'SCHOOL-FEE-IJMBE': ('schoolfee',),
    115 
    116             'ACCEPTANCE-FEE': ('clearance',),
    117             'ACCEPTANCE-FEE-PLUS': ('clearance_incl',),
    118             'ACCEPTANCE-FEE-PG': ('clearance',),
    119             'ACCEPTANCE-FEE-PT': ('clearance',),
    120             'ACCEPTANCE-FEE-PT-PLUS': ('clearance_incl',),
    121             'ACCEPTANCE-FEE-PT-PG': ('clearance',),
    122             'ACCEPTANCE-FEE-FP': ('clearance',),
    123             'ACCEPTANCE-FEE-IJMBE': ('clearance',),
    124 
    125             'APPLICATION-FEE-UTME': ('application',),
    126             'APPLICATION-FEE-PT': ('application',),
    127             'APPLICATION-FEE-FP': ('application',),
    128 
    129             'LATE-REGISTRATION': ('late_registration',),
    130             'LATE-REGISTRATION-PT': ('late_registration',),
    131 
    132             'AAU-STUDENT-WELFARE-ASSURANCE': ('welfare',),
    133             'AAU-STUDENT-WELFARE-ASSURANCE-PT': ('welfare',),
    134 
    135             'AAU-STUDENT-ID_CARD': ('id_card',),
    136 
    137             'HOSTEL-ACCOMMODATION-FEE': ('hostel_maintenance',),
    138             'HOSTEL-ACCOMMODATION-FEE-PT': ('hostel_maintenance',),
    139 
    140             'AAU-LAPEL-FILE-FEE': ('lapel',),
    141             'AAU-LAPEL-FILE-FEE-PT': ('lapel',),
    142 
    143             'MATRICULATION-GOWN-FEE': ('matric_gown',),
    144             'MATRICULATION-GOWN-FEE-PT': ('matric_gown',),
    145 
    146             'CONCESSIONAL-FEE': ('concessional',),
    147             'CONCESSIONAL-FEE-PT': ('concessional',),
    148 
    149             'STUDENTS-UNION-DUES': ('union',),
    150             'STUDENTS-UNION-DUES-PT': ('union',),
    151 
    152             'RESTITUTION-FEE': ('restitution',),
    153             }
    154 
    155         if PAYMENT_TYPE not in category_mapping.keys():
    156             self.output = ERROR_PART1 + 'Invalid PAYMENT_TYPE' + ERROR_PART2
    157             return
    158 
    159         # It seems eTranzact sends a POST request with an empty body but the URL
    160         # contains a query string. So it's actually a GET request pretended
    161         # to be a POST request. Although this does not comply with the
    162         # RFC 2616 HTTP guidelines we may try to fetch the id from the QUERY_STRING
    163         # value of the request.
    164         #if PAYEE_ID is None:
    165         #    try:
    166         #        PAYEE_ID = self.request['QUERY_STRING'].split('=')[1]
    167         #    except:
    168         #        self.output = '-4'
    169         #        return
    170 
    171         cat = getUtility(ICatalog, name='payments_catalog')
    172         results = list(cat.searchResults(p_id=(PAYEE_ID, PAYEE_ID)))
    173         if len(results) != 1:
    174             self.output = ERROR_PART1 + 'Invalid PAYEE_ID' + ERROR_PART2
    175             return
    176         student = getattr(results[0], 'student', None)
    177         amount = results[0].amount_auth
    178         payment_type = results[0].category
    179         p_category = results[0].p_category
    180         programme_type = results[0].p_item
    181         if not programme_type:
    182             programme_type = 'N/A'
    183         academic_session = academic_sessions_vocab.getTerm(
    184             results[0].p_session).title
    185         status = results[0].p_state
    186 
    187         if status == 'paid':
    188             self.output = ERROR_PART1 + 'PAYEE_ID already used' + ERROR_PART2
    189             return
    190         if p_category not in category_mapping[PAYMENT_TYPE]:
    191             self.output = ERROR_PART1 + 'Wrong PAYMENT_TYPE' + ERROR_PART2
    192             return
    193         if student and PAYMENT_TYPE.endswith('-RETURNING') \
    194             and student.state == CLEARED:
    195             self.output = ERROR_PART1 + 'Not a returning student' + ERROR_PART2
    196             return
    197         if student and PAYMENT_TYPE.endswith('-NEW') \
    198             and student.state != CLEARED:
    199             self.output = ERROR_PART1 + 'Not a new student' + ERROR_PART2
    200             return
    201         if student and '-PG' in PAYMENT_TYPE and not student.is_postgrad:
    202             self.output = ERROR_PART1 + 'Not a postgrad student' + ERROR_PART2
    203             return
    204         if student and '-PG' not in PAYMENT_TYPE and student.is_postgrad \
    205             and results[0].p_item != 'Balance':
    206             self.output = ERROR_PART1 + 'Postgrad student' + ERROR_PART2
    207             return
    208         if student and '-PT' in PAYMENT_TYPE \
    209             and not student.current_mode.endswith('_pt'):
    210             self.output = ERROR_PART1 + 'Not a part-time student' + ERROR_PART2
    211             return
    212         if student and '-PT' not in PAYMENT_TYPE \
    213             and student.current_mode.endswith('_pt'):
    214             self.output = ERROR_PART1 + 'Part-time student' + ERROR_PART2
    215             return
    216         if student and '-FP' in PAYMENT_TYPE and student.current_mode != 'found':
    217             self.output = ERROR_PART1 + 'Not a foundation programme student' + ERROR_PART2
    218             return
    219         if student and '-FP' not in PAYMENT_TYPE and student.current_mode == 'found':
    220             self.output = ERROR_PART1 + 'Foundation programme student' + ERROR_PART2
    221             return
    222         if student and '-IJMBE' in PAYMENT_TYPE and student.current_mode != 'ijmbe':
    223             self.output = ERROR_PART1 + 'Not IJMBE student' + ERROR_PART2
    224             return
    225         if student and '-IJMBE' not in PAYMENT_TYPE and student.current_mode == 'ijmbe':
    226             self.output = ERROR_PART1 + 'IJMBE student student' + ERROR_PART2
    227             return
    228         if '-BALANCE' in PAYMENT_TYPE and results[0].p_item != 'Balance':
    229             self.output = ERROR_PART1 + 'Not a balance payment' + ERROR_PART2
    230             return
    231         if not '-BALANCE' in PAYMENT_TYPE and results[0].p_item == 'Balance':
    232             self.output = ERROR_PART1 + 'Balance payment' + ERROR_PART2
    233             return
    234 
    235         try:
    236             owner = IPayer(results[0])
    237             full_name = owner.display_fullname
    238             matric_no = owner.id
    239             faculty = owner.faculty
    240             department = owner.department
    241             study_type = owner.current_mode
    242             email = owner.email
    243             phone = owner.phone
    244             level = owner.current_level
    245         except (TypeError, AttributeError):
    246             self.output = ERROR_PART1 +  'Unknown error' + ERROR_PART2
    247             return
    248         self.output = (
    249             'PayeeName=%s~' +
    250             'Faculty=%s~' +
    251             'Department=%s~' +
    252             'Level=%s~' +
    253             'ProgrammeType=%s~' +
    254             'StudyType=%s~' +
    255             'Session=%s~' +
    256             'PayeeID=%s~' +
    257             'Amount=%s~' +
    258             'FeeStatus=%s~' +
    259             'Semester=N/A~' +
    260             'PaymentType=%s~' +
    261             'MatricNumber=%s~' +
    262             'Email=%s~' +
    263             'PhoneNumber=%s'
    264 
    265             ) % (full_name, faculty,
    266             department, level, programme_type, study_type,
    267             academic_session, PAYEE_ID, amount, status, payment_type,
    268             matric_no, email, phone)
    269         return
    270 
    271 
    272 # Requerying eTranzact payments
    273 
    274 TERMINAL_ID = '0570000070'
    275 QUERY_URL =   'https://www.etranzact.net/WebConnectPlus/query.jsp'
    276 
    277 # Test environment
    278 #QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'
    279 #TERMINAL_ID = '5009892289'
    280 
    281 def query_etranzact(confirmation_number, payment):
    282    
    283     postdict = {}
    284     postdict['TERMINAL_ID'] = TERMINAL_ID
    285     #postdict['RESPONSE_URL'] = 'http://dummy'
    286     postdict['CONFIRMATION_NO'] = confirmation_number
    287     data = urllib.urlencode(postdict)
    288     payment.conf_number = confirmation_number
    289     try:
    290         # eTranzact only accepts HTTP 1.1 requests. Therefore
    291         # the urllib2 package is required here.
    292         f = urllib2.urlopen(url=QUERY_URL, data=data)
    293         success = f.read()
    294         success = success.replace('\r\n','')
    295         # eTranzact sends strange HTML tags which must be removed.
    296         success = re.sub("<.*?>", "", success)
    297         if 'CUSTOMER_ID' not in success:
    298             msg = _('Invalid or unsuccessful callback: ${a}',
    299                 mapping = {'a': success})
    300             log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
    301             payment.p_state = 'failed'
    302             return False, msg, log
    303         success = success.replace('%20',' ').split('&')
    304         # We expect at least two parameters
    305         if len(success) < 2:
    306             msg = _('Invalid callback: ${a}', mapping = {'a': success})
    307             log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
    308             payment.p_state = 'failed'
    309             return False, msg, log
    310         try:
    311             success_dict = dict([tuple(i.split('=')) for i in success])
    312         except ValueError:
    313             msg = _('Invalid callback: ${a}', mapping = {'a': success})
    314             log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
    315             payment.p_state = 'failed'
    316             return False, msg, log
    317     except IOError:
    318         msg = _('eTranzact IOError')
    319         log = 'eTranzact IOError'
    320         return False, msg, log
    321     payment.r_code = u'ET'
    322     payment.r_company = u'etranzact'
    323     payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
    324     payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
    325     payment.r_card_num = None
    326     payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
    327     if payment.r_amount_approved != payment.amount_auth:
    328         msg = _('Wrong amount')
    329         log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
    330         payment.p_state = 'failed'
    331         return False, msg, log
    332     customer_id = success_dict.get('CUSTOMER_ID')
    333     if payment.p_id != customer_id:
    334         msg = _('Wrong payment id')
    335         log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
    336         payment.p_state = 'failed'
    337         return False, msg, log
    338     log = 'valid callback for payment %s: %s' % (payment.p_id, success)
    339     msg = _('Successful callback received')
    340     payment.p_state = 'paid'
    341     payment.payment_date = datetime.utcnow()
    342     return True, msg, log
    343 
    344 class EtranzactEnterPinActionButtonApplicant(APABApplicant):
    345     grok.context(ICustomApplicantOnlinePayment)
    346     grok.require('waeup.payApplicant')
    347     grok.order(3)
    348     icon = 'actionicon_call.png'
    349     text = _('Query eTranzact History')
    350     target = 'enterpin'
    351 
    352 class EtranzactEnterPinActionButtonStudent(APABStudent):
    353     grok.context(ICustomStudentOnlinePayment)
    354     grok.require('waeup.payStudent')
    355     grok.order(3)
    356     icon = 'actionicon_call.png'
    357     text = _('Query eTranzact History')
    358     target = 'enterpin'
    359 
    360 class EtranzactEnterPinPageStudent(KofaPage):
    361     """
    362     """
    363     grok.context(ICustomStudentOnlinePayment)
    364     grok.name('enterpin')
    365     grok.template('enterpin')
    366     grok.require('waeup.payStudent')
    367 
    368     buttonname = _('Submit to eTranzact')
    369     label = _('Requery eTranzact History')
    370     action = 'query_history'
    371     placeholder = _('Confirmation Number (PIN)')
    372 
    373     def update(self):
    374         super(EtranzactEnterPinPageStudent, self).update()
    375         if not self.context.p_category.startswith('schoolfee'):
    376             return
    377         student = self.context.student
    378         if student.state != CLEARED:
    379             return
    380         if student.entry_session < 2013:
    381             return
    382         for ticket in student['payments'].values():
    383             if ticket.p_state == 'paid' and \
    384                 ticket.p_category.startswith('clearance'):
    385                 return
    386         self.flash(_('Please pay acceptance fee first.'), type="danger")
    387         self.redirect(self.url(self.context, '@@index'))
    388         return
    389 
    390 class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
    391     """
    392     """
    393     grok.require('waeup.payApplicant')
    394     grok.context(ICustomApplicantOnlinePayment)
    395 
    396 class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
    397     """ Query history of eTranzact payments
    398     """
    399     grok.context(ICustomStudentOnlinePayment)
    400     grok.name('query_history')
    401     grok.require('waeup.payStudent')
    402 
    403     def update(self, confirmation_number=None):
    404         if self.context.p_state == 'paid':
    405             self.flash(_('This ticket has already been paid.'))
    406             return
    407         student = self.context.student
    408         success, msg, log = query_etranzact(confirmation_number,self.context)
    409         student.writeLogMessage(self, log)
    410         if not success:
    411             self.flash(msg)
    412             return
    413         flashtype, msg, log = self.context.doAfterStudentPayment()
    414         if log is not None:
    415             student.writeLogMessage(self, log)
    416         self.flash(msg, type=flashtype)
    417         return
    418 
    419     def render(self):
    420         self.redirect(self.url(self.context, '@@index'))
    421         return
    422 
    423 class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
    424     """ Query history of eTranzact payments
    425     """
    426     grok.context(ICustomApplicantOnlinePayment)
    427     grok.name('query_history')
    428     grok.require('waeup.payApplicant')
    429 
    430     def update(self, confirmation_number=None):
    431         ob_class = self.__implemented__.__name__
    432         if self.context.p_state == 'paid':
    433             self.flash(_('This ticket has already been paid.'))
    434             return
    435         applicant = self.context.__parent__
    436         success, msg, log = query_etranzact(confirmation_number,self.context)
    437         applicant.writeLogMessage(self, log)
    438         if not success:
    439             self.flash(msg)
    440             return
    441         flashtype, msg, log = self.context.doAfterApplicantPayment()
    442         if log is not None:
    443             applicant.writeLogMessage(self, log)
    444         self.flash(msg, type=flashtype)
    445         return
    446 
    447     def render(self):
    448         self.redirect(self.url(self.context, '@@index'))
    449         return
    450 
    451 # Disable Interswitch viewlets. This could be avoided by defining the
    452 # action button viewlets of kofacustom.nigeria.interswitch.browser in the
    453 # context of INigeriaStudentOnlinePayment or INigeriaApplicantOnlinePayment
    454 # respectively. But then all interswitch.browser modules have to be extended.
    455 
    456 #class InterswitchActionButtonStudent(InterswitchActionButtonStudent):
    457 
    458 #    @property
    459 #    def target_url(self):
    460 #        return ''
    461 
    462 #class InterswitchRequestWebserviceActionButtonStudent(
    463 #    InterswitchRequestWebserviceActionButtonStudent):
    464 
    465 #    @property
    466 #    def target_url(self):
    467 #        return ''
    468 
    469 #class InterswitchActionButtonApplicant(InterswitchActionButtonApplicant):
    470 
    471 #    @property
    472 #    def target_url(self):
    473 #        return ''
    474 
    475 #class InterswitchRequestWebserviceActionButtonApplicant(
    476 #    InterswitchRequestWebserviceActionButtonApplicant):
    477 
    478 #    @property
    479 #    def target_url(self):
    480 #        return ''
Note: See TracChangeset for help on using the changeset viewer.