source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/etranzact/studentsbrowser.py @ 16246

Last change on this file since 16246 was 16246, checked in by Henrik Bettermann, 4 years ago

Fallback: Check current year session if session object does not exist.

File size: 8.8 KB
Line 
1## $Id: studentsbrowser.py 15599 2019-09-20 13:24:59Z henrik $
2##
3## Copyright (C) 2017 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##
18import grok
19import hashlib
20from datetime import datetime, timedelta
21from zope.component import getUtility
22from zope.security import checkPermission
23from waeup.kofa.interfaces import IKofaUtils
24from waeup.kofa.utils.helpers import to_timezone
25from waeup.kofa.browser.layout import UtilityView, KofaPage
26from waeup.kofa.browser.viewlets import ManageActionButton
27from kofacustom.nigeria.etranzact.helpers import (
28    write_payments_log, process_response, query_history)
29from kofacustom.nigeria.students.browser import NigeriaOnlinePaymentDisplayFormPage as NOPDPStudent
30from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
31from kofacustom.nigeria.students.interfaces import INigeriaStudentOnlinePayment
32from kofacustom.nigeria.interfaces import MessageFactory as _
33
34from kofacustom.nigeria.etranzact.tests import (
35    TERMINAL_ID, HOST, HTTPS, SECRET_KEY, LOGO_URL, GATEWAY_AMT)
36
37grok.templatedir('browser_templates')
38
39def webconnect_module_activated(session, payment):
40    if payment.r_company and payment.r_company != 'etranzact':
41        return False
42    try:
43        return getattr(grok.getSite()['configuration'][str(session)],
44            'etranzact_webconnect_enabled', False)
45    except KeyError:
46        session = datetime.now().year
47        try:
48            return getattr(grok.getSite()['configuration'][str(session)],
49                'etranzact_webconnect_enabled', False)
50        except KeyError:
51            return False
52
53class EtranzactActionButtonStudent(ManageActionButton):
54    grok.order(1)
55    grok.context(INigeriaOnlinePayment)
56    grok.view(NOPDPStudent)
57    grok.require('waeup.payStudent')
58    icon = 'actionicon_pay.png'
59    text = _('Pay via Etranzact WebConnect')
60    target = 'goto_etranzact'
61
62    @property
63    def target_url(self):
64        if not webconnect_module_activated(
65            self.context.student.current_session, self.context):
66            return ''
67        if self.context.p_state != 'unpaid':
68            return ''
69        return self.view.url(self.view.context, self.target)
70
71class EtranzactRequeryActionButtonStudent(ManageActionButton):
72    grok.order(2)
73    grok.context(INigeriaOnlinePayment)
74    grok.view(NOPDPStudent)
75    grok.require('waeup.payStudent')
76    icon = 'actionicon_call.png'
77    text = _('Requery Etranzact WebConnect History')
78    target = 'requery_history'
79
80    @property
81    def target_url(self):
82        if not webconnect_module_activated(
83            self.context.student.current_session, self.context):
84            return ''
85        if self.context.p_state in ('paid', 'waived', 'scholarship'):
86            return ''
87        return self.view.url(self.view.context, self.target)
88
89class EtranzactPageStudent(KofaPage):
90    """ View which sends a POST request to the Etranzact payment gateway.
91    """
92    grok.context(INigeriaStudentOnlinePayment)
93    grok.name('goto_etranzact')
94    grok.template('goto_etranzact')
95    grok.require('waeup.payStudent')
96    label = _('Pay via Etranzact')
97    submit_button = _('Pay now')
98
99    host = HOST
100    https = HTTPS
101    secret_key = SECRET_KEY
102    terminal_id = TERMINAL_ID
103    logo_url = LOGO_URL
104    gateway_amt = GATEWAY_AMT
105
106    @property
107    def action(self):
108        if self.https:
109            return 'https://' + self.host + '/webconnect/v3/caller.jsp'
110        return 'http://' + self.host + '/webconnect/v3/caller.jsp'
111
112    def init_update(self):
113        if self.context.p_state == 'paid':
114            return _("Payment ticket can't be re-sent to Etranzact.")
115        now = datetime.utcnow()
116        if self.context.creation_date.tzinfo is not None:
117            # That's bad. Please store timezone-naive datetimes only!
118            now = self.context.creation_date.tzinfo.localize(now)
119        time_delta = now - self.context.creation_date
120        if time_delta.days > 7:
121            return _("This payment ticket is too old. Please create a new ticket.")
122        # In contrast to the procedure in the Remita and Interswitch modules,
123        # we do not call requery_history but receive and evaluate
124        # the response form from Etranzact directly. This is possible
125        # because Etranzact provides the FINAL_CHECKSUM hash value
126        # which authenticates the response.
127        self.responseurl = self.url(self.context, 'receive_etranzact')
128        self.transaction_id = self.context.p_id
129        hashargs =      self.amount + self.terminal_id + self.transaction_id \
130            + self.responseurl + self.secret_key
131        self.hashvalue = hashlib.md5(hashargs).hexdigest()
132        self.customer = self.context.student
133        return
134
135    def update(self):
136        if not webconnect_module_activated(
137            self.context.student.current_session, self.context):
138            self.flash(_('Forbidden'), type='danger')
139            self.redirect(self.url(self.context, '@@index'))
140            return
141        # Already now it becomes an Etranzact payment. We set the net amount
142        # and add the gateway amount.
143        if not self.context.r_company:
144            self.context.net_amt = self.context.amount_auth
145            self.context.amount_auth += self.gateway_amt
146            self.context.gateway_amt = self.gateway_amt
147            self.context.r_company = u'etranzact'
148        self.amount = "%.1f" % self.context.amount_auth
149        error = self.init_update()
150        if error:
151            self.flash(error, type='danger')
152            self.redirect(self.url(self.context, '@@index'))
153            return
154        return
155
156class EtranzactReceiveResponseStudent(NOPDPStudent):
157    """ View that receives the response from eTrantact payment gateway.
158    """
159    grok.name('receive_etranzact')
160
161    secret_key = SECRET_KEY
162    terminal_id = TERMINAL_ID
163
164    def update(self):
165        super(EtranzactReceiveResponseStudent, self).update()
166        if not webconnect_module_activated(
167            self.context.student.current_session, self.context):
168            self.flash(_('Forbidden'), type='danger')
169            self.redirect(self.url(self.context, '@@index'))
170            return
171        student = self.context.student
172        form = self.request.form
173        verify = False
174        if self.context.p_state == 'paid':
175            verify = True
176        success, msg, log = process_response(self.context, form, self, verify)
177        student.writeLogMessage(self, log)
178        if not success:
179            self.flash(msg, type='danger')
180            return
181        write_payments_log(student.student_id, self.context)
182        flashtype, msg, log = self.context.doAfterStudentPayment()
183        if log is not None:
184            student.writeLogMessage(self, log)
185        self.flash(msg, type=flashtype)
186        return
187
188class EtranzactRequestPaymentStatusPageStudent(UtilityView, grok.View):
189    """ Request webservice view for the Etranzact gateway.
190    """
191    grok.context(INigeriaStudentOnlinePayment)
192    grok.name('requery_history')
193    grok.require('waeup.payStudent')
194
195    host = HOST
196    https = HTTPS
197    secret_key = SECRET_KEY
198    terminal_id = TERMINAL_ID
199    logo_url = LOGO_URL
200
201    def update(self):
202        if not webconnect_module_activated(
203            self.context.student.current_session, self.context):
204            self.flash(_('Forbidden'), type='danger')
205            self.redirect(self.url(self.context, '@@index'))
206            return
207        if self.context.p_state in ('paid', 'waived', 'scholarship'):
208            self.flash(_('This ticket has already been paid.'), type='danger')
209            return
210        student = self.context.student
211        verify = False
212        raw, form = query_history(self.host, self.terminal_id,
213                                  self.context.p_id, self.https)
214        success, msg, log = process_response(self.context, form, self, verify)
215        student.writeLogMessage(self, log)
216        if not success:
217            self.flash(msg, type='danger')
218            return
219        write_payments_log(student.student_id, self.context)
220        flashtype, msg, log = self.context.doAfterStudentPayment()
221        if log is not None:
222            student.writeLogMessage(self, log)
223        self.flash(msg, type=flashtype)
224        return
225
226    def render(self):
227        self.redirect(self.url(self.context))
228        return
Note: See TracBrowser for help on using the repository browser.