source: main/waeup.aaue/trunk/src/waeup/aaue/etranzact/browser.py @ 8743

Last change on this file since 8743 was 8734, checked in by Henrik Bettermann, 13 years ago

Change terminal id again.

  • Property svn:keywords set to Id
File size: 8.9 KB
RevLine 
[7929]1## $Id: browser.py 8734 2012-06-15 13:37:40Z henrik $
2##
3## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18from datetime import datetime
19import httplib
20import urllib
21from xml.dom.minidom import parseString
22import grok
[8704]23from zope.component import getUtility
24from zope.catalog.interfaces import ICatalog
[8698]25from waeup.kofa.interfaces import IUniversity
[8704]26from waeup.kofa.payments.interfaces import IPaymentWebservice
[7929]27from waeup.kofa.browser.layout import KofaPage, UtilityView
[8430]28from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
29from waeup.kofa.applicants.viewlets import ApprovePaymentActionButton as APABApplicant
[8710]30from waeup.aaue.interfaces import academic_sessions_vocab
[8444]31from waeup.aaue.interfaces import MessageFactory as _
32from waeup.aaue.students.interfaces import ICustomStudentOnlinePayment
33from waeup.aaue.applicants.interfaces import ICustomApplicantOnlinePayment
[7929]34
[8698]35# Kofa's webservice
36
37class KofaFeeRequest(grok.View):
38    grok.context(IUniversity)
39    grok.name('feerequest')
40    grok.require('waeup.Public')
41
42    def update(self, PAYEE_ID=None):
[8704]43        cat = getUtility(ICatalog, name='payments_catalog')
44        results = list(cat.searchResults(p_id=(PAYEE_ID, PAYEE_ID)))
45        if len(results) != 1:
46            self.output = '-1'
[8698]47        else:
[8704]48            try:
[8710]49                owner = IPaymentWebservice(results[0])
50                full_name = owner.display_fullname
51                matric_no = owner.id
52                faculty = owner.faculty
53                department = owner.department
[8704]54            except (TypeError, AttributeError):
55                self.output = '-1'
56                return
57            amount = results[0].amount_auth
[8710]58            payment_type = results[0].category
59            programme_type = results[0].p_item
60            academic_session = academic_sessions_vocab.getTerm(
61                results[0].p_session).title
62            status = results[0].p_state
[8733]63            self.output = (
64                'FULL_NAME=%s&' +
[8726]65                'FACULTY=%s&' +
[8733]66                'DEPARTMENT=%s&' +
67                'RETURN_TYPE=%s&' +
68                'PROGRAMME_TYPE=%s&' +
69                'PAYMENT_TYPE=%s&' +
70                'ACADEMIC_SESSION=%s&' +
71                'MATRIC_NO=%s&' +
72                'FEE_AMOUNT=%s&' +
73                'TRANSACTION_STATUS=%s') % (full_name, faculty,
74                department, PAYEE_ID, programme_type, payment_type,
75                academic_session, matric_no, amount, status)
[8698]76        return
77
78    def render(self):
79        return self.output
80
81
82# Requerying eTranzact payments
83
[8682]84#TERMINAL_ID = '0330000046'
[8680]85#QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
[8259]86
[8680]87# Test environment
88QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'
[8734]89TERMINAL_ID = '5009892289'
[8680]90
[8430]91def query_etranzact(confirmation_number, payment):
92   
[8247]93    postdict = {}
94    postdict['TERMINAL_ID'] = TERMINAL_ID
95    #postdict['RESPONSE_URL'] = 'http://dummy'
96    postdict['CONFIRMATION_NO'] = confirmation_number
97    data = urllib.urlencode(postdict)
[8682]98    payment.conf_number = confirmation_number
[8247]99    try:
100        f = urllib.urlopen(url=QUERY_URL, data=data)
101        success = f.read()
[8432]102        success = success.replace('\r\n','')
[8247]103        if 'COL1' not in success:
[8430]104            msg = _('Invalid or unsuccessful callback: ${a}',
105                mapping = {'a': success})
106            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
[8247]107            payment.p_state = 'failed'
[8430]108            return False, msg, log
[8247]109        success = success.replace('%20',' ').split('&')
110        # We expect at least two parameters
111        if len(success) < 2:
[8430]112            msg = _('Invalid callback: ${a}', mapping = {'a': success})
113            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
[8247]114            payment.p_state = 'failed'
[8430]115            return False, msg, log
[8247]116        try:
117            success_dict = dict([tuple(i.split('=')) for i in success])
118        except ValueError:
[8430]119            msg = _('Invalid callback: ${a}', mapping = {'a': success})
120            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
[8247]121            payment.p_state = 'failed'
[8430]122            return False, msg, log
[8247]123    except IOError:
[8430]124        msg = _('eTranzact IOError')
125        log = 'eTranzact IOError'
126        return False, msg, log
[8247]127    payment.r_code = u'ET'
128    payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
129    payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
130    payment.r_card_num = None
131    payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
132    if payment.r_amount_approved != payment.amount_auth:
[8430]133        msg = _('Wrong amount')
134        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
[8247]135        payment.p_state = 'failed'
[8430]136        return False, msg, log
[8717]137    #tcode = payment.p_id
138    #tcode = tcode[len(tcode)-8:len(tcode)]
[8247]139    col1 = success_dict.get('COL1')
[8717]140    #col1 = col1[len(col1)-8:len(col1)]
141    #if tcode != col1:
142    if payment.p_id != col1:
143        #msg = _('Wrong transaction code')
144        msg = _('Wrong payment id')
[8430]145        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
[8247]146        payment.p_state = 'failed'
[8430]147        return False, msg, log
148    log = 'valid callback for payment %s: %s' % (payment.p_id, success)
149    msg = _('Successful callback received')
[8247]150    payment.p_state = 'paid'
[8433]151    payment.payment_date = datetime.utcnow()
[8430]152    return True, msg, log
[8247]153
[8430]154class EtranzactEnterPinActionButtonApplicant(APABApplicant):
[8253]155    grok.context(ICustomApplicantOnlinePayment)
[8430]156    grok.require('waeup.payApplicant')
[8259]157    grok.order(3)
[7929]158    icon = 'actionicon_call.png'
159    text = _('Query eTranzact History')
[7976]160    target = 'enterpin'
[7929]161
[8430]162class EtranzactEnterPinActionButtonStudent(APABStudent):
[8253]163    grok.context(ICustomStudentOnlinePayment)
[8430]164    grok.require('waeup.payStudent')
[8259]165    grok.order(3)
[8247]166    icon = 'actionicon_call.png'
167    text = _('Query eTranzact History')
168    target = 'enterpin'
169
170class EtranzactEnterPinPageStudent(KofaPage):
[7976]171    """
172    """
[8253]173    grok.context(ICustomStudentOnlinePayment)
[7976]174    grok.name('enterpin')
175    grok.template('enterpin')
[7929]176    grok.require('waeup.payStudent')
177
[7976]178    buttonname = _('Submit to eTranzact')
179    label = _('Requery eTranzact History')
180    action = 'query_history'
[7929]181
[8247]182class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
183    """
184    """
185    grok.require('waeup.payApplicant')
[8253]186    grok.context(ICustomApplicantOnlinePayment)
[8247]187
188class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
[7929]189    """ Query history of eTranzact payments
190    """
[8253]191    grok.context(ICustomStudentOnlinePayment)
[7929]192    grok.name('query_history')
193    grok.require('waeup.payStudent')
194
195    def update(self, confirmation_number=None):
[8430]196        ob_class = self.__implemented__.__name__
[7929]197        if self.context.p_state == 'paid':
198            self.flash(_('This ticket has already been paid.'))
199            return
200        student = self.context.getStudent()
[8430]201        success, msg, log = query_etranzact(confirmation_number,self.context)
202        student.loggerInfo(ob_class, log)
203        if not success:
204            self.flash(msg)
205            return
206        success, msg, log = self.context.doAfterStudentPayment()
207        if log is not None:
208            student.loggerInfo(ob_class, log)
209        self.flash(msg)
[8247]210        return
[7929]211
[8247]212    def render(self):
213        self.redirect(self.url(self.context, '@@index'))
214        return
[7929]215
[8247]216class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
217    """ Query history of eTranzact payments
218    """
[8253]219    grok.context(ICustomApplicantOnlinePayment)
[8247]220    grok.name('query_history')
221    grok.require('waeup.payApplicant')
222
223    def update(self, confirmation_number=None):
[8430]224        ob_class = self.__implemented__.__name__
[8247]225        if self.context.p_state == 'paid':
226            self.flash(_('This ticket has already been paid.'))
[7929]227            return
[8247]228        applicant = self.context.__parent__
[8430]229        success, msg, log = query_etranzact(confirmation_number,self.context)
230        applicant.loggerInfo(ob_class, log)
231        if not success:
232            self.flash(msg)
233            return
234        success, msg, log = self.context.doAfterApplicantPayment()
235        if log is not None:
236            applicant.loggerInfo(ob_class, log)
237        self.flash(msg)
[7929]238        return
239
240    def render(self):
241        self.redirect(self.url(self.context, '@@index'))
[8259]242        return
Note: See TracBrowser for help on using the repository browser.