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

Last change on this file since 8733 was 8733, checked in by Henrik Bettermann, 12 years ago

It seems that also the order is important.

  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1## $Id: browser.py 8733 2012-06-15 12:17:30Z 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 = (
64                'FULL_NAME=%s&' +
65                'FACULTY=%s&' +
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)
76        return
77
78    def render(self):
79        return self.output
80
81
82# Requerying eTranzact payments
83
84#TERMINAL_ID = '0330000046'
85#QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
86
87# Test environment
88QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'
89TERMINAL_ID = '5009892287'
90
91def query_etranzact(confirmation_number, payment):
92   
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)
98    payment.conf_number = confirmation_number
99    try:
100        f = urllib.urlopen(url=QUERY_URL, data=data)
101        success = f.read()
102        success = success.replace('\r\n','')
103        if 'COL1' not in success:
104            msg = _('Invalid or unsuccessful callback: ${a}',
105                mapping = {'a': success})
106            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
107            payment.p_state = 'failed'
108            return False, msg, log
109        success = success.replace('%20',' ').split('&')
110        # We expect at least two parameters
111        if len(success) < 2:
112            msg = _('Invalid callback: ${a}', mapping = {'a': success})
113            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
114            payment.p_state = 'failed'
115            return False, msg, log
116        try:
117            success_dict = dict([tuple(i.split('=')) for i in success])
118        except ValueError:
119            msg = _('Invalid callback: ${a}', mapping = {'a': success})
120            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
121            payment.p_state = 'failed'
122            return False, msg, log
123    except IOError:
124        msg = _('eTranzact IOError')
125        log = 'eTranzact IOError'
126        return False, msg, log
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:
133        msg = _('Wrong amount')
134        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
135        payment.p_state = 'failed'
136        return False, msg, log
137    #tcode = payment.p_id
138    #tcode = tcode[len(tcode)-8:len(tcode)]
139    col1 = success_dict.get('COL1')
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')
145        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
146        payment.p_state = 'failed'
147        return False, msg, log
148    log = 'valid callback for payment %s: %s' % (payment.p_id, success)
149    msg = _('Successful callback received')
150    payment.p_state = 'paid'
151    payment.payment_date = datetime.utcnow()
152    return True, msg, log
153
154class EtranzactEnterPinActionButtonApplicant(APABApplicant):
155    grok.context(ICustomApplicantOnlinePayment)
156    grok.require('waeup.payApplicant')
157    grok.order(3)
158    icon = 'actionicon_call.png'
159    text = _('Query eTranzact History')
160    target = 'enterpin'
161
162class EtranzactEnterPinActionButtonStudent(APABStudent):
163    grok.context(ICustomStudentOnlinePayment)
164    grok.require('waeup.payStudent')
165    grok.order(3)
166    icon = 'actionicon_call.png'
167    text = _('Query eTranzact History')
168    target = 'enterpin'
169
170class EtranzactEnterPinPageStudent(KofaPage):
171    """
172    """
173    grok.context(ICustomStudentOnlinePayment)
174    grok.name('enterpin')
175    grok.template('enterpin')
176    grok.require('waeup.payStudent')
177
178    buttonname = _('Submit to eTranzact')
179    label = _('Requery eTranzact History')
180    action = 'query_history'
181
182class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
183    """
184    """
185    grok.require('waeup.payApplicant')
186    grok.context(ICustomApplicantOnlinePayment)
187
188class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
189    """ Query history of eTranzact payments
190    """
191    grok.context(ICustomStudentOnlinePayment)
192    grok.name('query_history')
193    grok.require('waeup.payStudent')
194
195    def update(self, confirmation_number=None):
196        ob_class = self.__implemented__.__name__
197        if self.context.p_state == 'paid':
198            self.flash(_('This ticket has already been paid.'))
199            return
200        student = self.context.getStudent()
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)
210        return
211
212    def render(self):
213        self.redirect(self.url(self.context, '@@index'))
214        return
215
216class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
217    """ Query history of eTranzact payments
218    """
219    grok.context(ICustomApplicantOnlinePayment)
220    grok.name('query_history')
221    grok.require('waeup.payApplicant')
222
223    def update(self, confirmation_number=None):
224        ob_class = self.__implemented__.__name__
225        if self.context.p_state == 'paid':
226            self.flash(_('This ticket has already been paid.'))
227            return
228        applicant = self.context.__parent__
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)
238        return
239
240    def render(self):
241        self.redirect(self.url(self.context, '@@index'))
242        return
Note: See TracBrowser for help on using the repository browser.