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

Last change on this file since 15800 was 15796, checked in by Henrik Bettermann, 5 years ago

Payment slip must not be downloadable before adding surcharges.

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