source: main/waeup.uniben/trunk/src/waeup/uniben/etranzact/browser.py @ 8247

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

Reorganize payment customizatiom. Tests will follow.

Let also applicants pay via eTranzact. Show transaction code on display view (slip view will follow).

  • Property svn:keywords set to Id
File size: 6.4 KB
Line 
1## $Id: browser.py 8247 2012-04-22 12:56:07Z 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 waeup.kofa.browser.layout import KofaPage, UtilityView
24from waeup.kofa.students.interfaces import IStudentOnlinePayment
25from waeup.kofa.applicants.interfaces import IApplicantOnlinePayment
26from waeup.kofa.applicants.viewlets import RequestCallbackActionButton as RCABApplicant
27from waeup.kofa.students.viewlets import RequestCallbackActionButton as RCABStudent
28from waeup.uniben.interfaces import MessageFactory as _
29from waeup.uniben.students.utils import actions_after_student_payment
30from waeup.uniben.applicants.utils import actions_after_applicant_payment
31
32TERMINAL_ID = '0500000003'
33QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
34
35
36def query_etranzact(confirmation_number, user, payment, view):
37    ob_class = view.__implemented__.__name__.replace('waeup.kofa.','')
38    postdict = {}
39    postdict['TERMINAL_ID'] = TERMINAL_ID
40    #postdict['RESPONSE_URL'] = 'http://dummy'
41    postdict['CONFIRMATION_NO'] = confirmation_number
42    data = urllib.urlencode(postdict)
43    try:
44        f = urllib.urlopen(url=QUERY_URL, data=data)
45        success = f.read()
46        user.loggerInfo(ob_class, 'callback received: %s' % success)
47        if 'COL1' not in success:
48            view.flash(_('Invalid or unsuccessful callback: ${a}',
49                mapping = {'a': success}))
50            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
51            payment.p_state = 'failed'
52            return False
53        success = success.replace('%20',' ').split('&')
54        # We expect at least two parameters
55        if len(success) < 2:
56            view.flash(_('Invalid callback: ${a}',
57                mapping = {'a': success}))
58            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
59            payment.p_state = 'failed'
60            return False
61        try:
62            success_dict = dict([tuple(i.split('=')) for i in success])
63        except ValueError:
64            view.flash(_('Invalid callback: ${a}',
65                mapping = {'a': success}))
66            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
67            payment.p_state = 'failed'
68            return False
69    except IOError:
70        view.flash(_('eTranzact IOError'))
71        return False
72    payment.r_code = u'ET'
73    payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
74    payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
75    payment.r_card_num = None
76    payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
77    if payment.r_amount_approved != payment.amount_auth:
78        view.flash(_('Wrong amount'))
79        user.loggerInfo(ob_class, 'successful callback but wrong amount: %s'
80            % payment.p_id)
81        payment.p_state = 'failed'
82        return False
83    tcode = payment.p_id
84    tcode = tcode[len(tcode)-8:len(tcode)]
85    col1 = success_dict.get('COL1')
86    col1 = col1[len(col1)-8:len(col1)]
87    if tcode != col1:
88        view.flash(_('Wrong transaction code'))
89        write_log_message(
90            view,'successful callback but wrong transaction code: %s'
91            % payment.p_id)
92        user.loggerInfo(ob_class, 'successful callback wrong transaction code: %s'
93            % payment.p_id)
94        payment.p_state = 'failed'
95        return False
96    user.loggerInfo(ob_class, 'successful callback: %s' % payment.p_id)
97    payment.p_state = 'paid'
98    payment.payment_date = datetime.now()
99    return True
100
101class EtranzactEnterPinActionButtonApplicant(RCABApplicant):
102    icon = 'actionicon_call.png'
103    text = _('Query eTranzact History')
104    target = 'enterpin'
105
106class EtranzactEnterPinActionButtonStudent(RCABStudent):
107    icon = 'actionicon_call.png'
108    text = _('Query eTranzact History')
109    target = 'enterpin'
110
111class EtranzactEnterPinPageStudent(KofaPage):
112    """
113    """
114    grok.context(IStudentOnlinePayment)
115    grok.name('enterpin')
116    grok.template('enterpin')
117    grok.require('waeup.payStudent')
118
119    buttonname = _('Submit to eTranzact')
120    label = _('Requery eTranzact History')
121    action = 'query_history'
122
123class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
124    """
125    """
126    grok.require('waeup.payApplicant')
127    grok.context(IApplicantOnlinePayment)
128
129class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
130    """ Query history of eTranzact payments
131    """
132    grok.context(IStudentOnlinePayment)
133    grok.name('query_history')
134    grok.require('waeup.payStudent')
135
136    def update(self, confirmation_number=None):
137        if self.context.p_state == 'paid':
138            self.flash(_('This ticket has already been paid.'))
139            return
140        student = self.context.getStudent()
141        if query_etranzact(confirmation_number, student, self.context, self):
142            actions_after_student_payment(student, self.context, self)
143        return
144
145    def render(self):
146        self.redirect(self.url(self.context, '@@index'))
147        return
148
149class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
150    """ Query history of eTranzact payments
151    """
152    grok.context(IApplicantOnlinePayment)
153    grok.name('query_history')
154    grok.require('waeup.payApplicant')
155
156    def update(self, confirmation_number=None):
157        if self.context.p_state == 'paid':
158            self.flash(_('This ticket has already been paid.'))
159            return
160        applicant = self.context.__parent__
161        if query_etranzact(confirmation_number, applicant, self.context, self):
162            actions_after_applicant_payment(applicant, self)
163        return
164
165    def render(self):
166        self.redirect(self.url(self.context, '@@index'))
167        return
Note: See TracBrowser for help on using the repository browser.