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

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

Add more webservice parameters.

  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1## $Id: browser.py 8710 2012-06-13 13:56:50Z 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
23from zope.component import getUtility
24from zope.catalog.interfaces import ICatalog
25from waeup.kofa.interfaces import IUniversity
26from waeup.kofa.payments.interfaces import IPaymentWebservice
27from waeup.kofa.browser.layout import KofaPage, UtilityView
28from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
29from waeup.kofa.applicants.viewlets import ApprovePaymentActionButton as APABApplicant
30from waeup.aaue.interfaces import academic_sessions_vocab
31from waeup.aaue.interfaces import MessageFactory as _
32from waeup.aaue.students.interfaces import ICustomStudentOnlinePayment
33from waeup.aaue.applicants.interfaces import ICustomApplicantOnlinePayment
34
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):
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'
47        else:
48            try:
49                owner = IPaymentWebservice(results[0])
50                full_name = owner.display_fullname
51                matric_no = owner.id
52                faculty = owner.faculty
53                department = owner.department
54            except (TypeError, AttributeError):
55                self.output = '-1'
56                return
57            amount = results[0].amount_auth
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
63            self.output = ('FULL_NAME1=%s&MATRIC_NO1=%s&' +
64                'ACADEMIC_SESSION1=%s&PAYMENT_TYPE1=%s&' +
65                'PAYMENT_TYPE3=&FACULTY1=%s&' +
66                'DEPARTMENT1=%s&PROGRAMME_TYPE1=%s&' +
67                'RETURN_TYPE1=&FEE_AMOUNT1=%s&' +
68                'TRANSACTION_STATUS1=%s') % (full_name, matric_no,
69                academic_session, payment_type, faculty, department,
70                programme_type, amount, status)
71        return
72
73    def render(self):
74        return self.output
75
76
77# Requerying eTranzact payments
78
79#TERMINAL_ID = '0330000046'
80#QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
81
82# Test environment
83QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'
84TERMINAL_ID = '5009892287'
85
86def query_etranzact(confirmation_number, payment):
87   
88    postdict = {}
89    postdict['TERMINAL_ID'] = TERMINAL_ID
90    #postdict['RESPONSE_URL'] = 'http://dummy'
91    postdict['CONFIRMATION_NO'] = confirmation_number
92    data = urllib.urlencode(postdict)
93    payment.conf_number = confirmation_number
94    try:
95        f = urllib.urlopen(url=QUERY_URL, data=data)
96        success = f.read()
97        success = success.replace('\r\n','')
98        if 'COL1' not in success:
99            msg = _('Invalid or unsuccessful callback: ${a}',
100                mapping = {'a': success})
101            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
102            payment.p_state = 'failed'
103            return False, msg, log
104        success = success.replace('%20',' ').split('&')
105        # We expect at least two parameters
106        if len(success) < 2:
107            msg = _('Invalid callback: ${a}', mapping = {'a': success})
108            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
109            payment.p_state = 'failed'
110            return False, msg, log
111        try:
112            success_dict = dict([tuple(i.split('=')) for i in success])
113        except ValueError:
114            msg = _('Invalid callback: ${a}', mapping = {'a': success})
115            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
116            payment.p_state = 'failed'
117            return False, msg, log
118    except IOError:
119        msg = _('eTranzact IOError')
120        log = 'eTranzact IOError'
121        return False, msg, log
122    payment.r_code = u'ET'
123    payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
124    payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
125    payment.r_card_num = None
126    payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
127    if payment.r_amount_approved != payment.amount_auth:
128        msg = _('Wrong amount')
129        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
130        payment.p_state = 'failed'
131        return False, msg, log
132    tcode = payment.p_id
133    tcode = tcode[len(tcode)-8:len(tcode)]
134    col1 = success_dict.get('COL1')
135    col1 = col1[len(col1)-8:len(col1)]
136    if tcode != col1:
137        msg = _('Wrong transaction code')
138        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
139        payment.p_state = 'failed'
140        return False, msg, log
141    log = 'valid callback for payment %s: %s' % (payment.p_id, success)
142    msg = _('Successful callback received')
143    payment.p_state = 'paid'
144    payment.payment_date = datetime.utcnow()
145    return True, msg, log
146
147class EtranzactEnterPinActionButtonApplicant(APABApplicant):
148    grok.context(ICustomApplicantOnlinePayment)
149    grok.require('waeup.payApplicant')
150    grok.order(3)
151    icon = 'actionicon_call.png'
152    text = _('Query eTranzact History')
153    target = 'enterpin'
154
155class EtranzactEnterPinActionButtonStudent(APABStudent):
156    grok.context(ICustomStudentOnlinePayment)
157    grok.require('waeup.payStudent')
158    grok.order(3)
159    icon = 'actionicon_call.png'
160    text = _('Query eTranzact History')
161    target = 'enterpin'
162
163class EtranzactEnterPinPageStudent(KofaPage):
164    """
165    """
166    grok.context(ICustomStudentOnlinePayment)
167    grok.name('enterpin')
168    grok.template('enterpin')
169    grok.require('waeup.payStudent')
170
171    buttonname = _('Submit to eTranzact')
172    label = _('Requery eTranzact History')
173    action = 'query_history'
174
175class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
176    """
177    """
178    grok.require('waeup.payApplicant')
179    grok.context(ICustomApplicantOnlinePayment)
180
181class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
182    """ Query history of eTranzact payments
183    """
184    grok.context(ICustomStudentOnlinePayment)
185    grok.name('query_history')
186    grok.require('waeup.payStudent')
187
188    def update(self, confirmation_number=None):
189        ob_class = self.__implemented__.__name__
190        if self.context.p_state == 'paid':
191            self.flash(_('This ticket has already been paid.'))
192            return
193        student = self.context.getStudent()
194        success, msg, log = query_etranzact(confirmation_number,self.context)
195        student.loggerInfo(ob_class, log)
196        if not success:
197            self.flash(msg)
198            return
199        success, msg, log = self.context.doAfterStudentPayment()
200        if log is not None:
201            student.loggerInfo(ob_class, log)
202        self.flash(msg)
203        return
204
205    def render(self):
206        self.redirect(self.url(self.context, '@@index'))
207        return
208
209class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
210    """ Query history of eTranzact payments
211    """
212    grok.context(ICustomApplicantOnlinePayment)
213    grok.name('query_history')
214    grok.require('waeup.payApplicant')
215
216    def update(self, confirmation_number=None):
217        ob_class = self.__implemented__.__name__
218        if self.context.p_state == 'paid':
219            self.flash(_('This ticket has already been paid.'))
220            return
221        applicant = self.context.__parent__
222        success, msg, log = query_etranzact(confirmation_number,self.context)
223        applicant.loggerInfo(ob_class, log)
224        if not success:
225            self.flash(msg)
226            return
227        success, msg, log = self.context.doAfterApplicantPayment()
228        if log is not None:
229            applicant.loggerInfo(ob_class, log)
230        self.flash(msg)
231        return
232
233    def render(self):
234        self.redirect(self.url(self.context, '@@index'))
235        return
Note: See TracBrowser for help on using the repository browser.