source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/etranzact/credobrowser.py @ 17783

Last change on this file since 17783 was 17783, checked in by Henrik Bettermann, 6 months ago

Use serviceCode.

  • Property svn:executable set to *
File size: 10.9 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, KofaEditFormPage, action, NullValidator
26from waeup.kofa.browser.viewlets import ManageActionButton
27from kofacustom.nigeria.etranzact.helpers import (
28    write_payments_log,
29    initiate_payment,
30    query_credo_payment)
31from kofacustom.nigeria.students.browser import NigeriaOnlinePaymentDisplayFormPage as NOPDPStudent
32from kofacustom.nigeria.applicants.browser import NigeriaOnlinePaymentDisplayFormPage as NOPDPApplicant
33from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
34from kofacustom.nigeria.students.interfaces import INigeriaStudentOnlinePayment
35from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment
36from kofacustom.nigeria.interfaces import MessageFactory as _
37
38from kofacustom.nigeria.etranzact.tests import (
39    TERMINAL_ID, CREDO_HOST, HTTPS, SECRET_API_KEY, API_PUBLIC_KEY,
40    LOGO_URL, GATEWAY_AMT)
41
42grok.templatedir('browser_templates')
43
44def credo_module_activated(session, payment):
45    if payment.p_currency != 'NGN':
46        return False
47    if payment.r_company and payment.r_company != 'etranzact':
48        return False
49    try:
50        return getattr(grok.getSite()['configuration'][str(session)],
51            'etranzact_credo_enabled', False)
52    except KeyError:
53        session = datetime.now().year
54        try:
55            return getattr(grok.getSite()['configuration'][str(session)],
56                'etranzact_credo_enabled', False)
57        except KeyError:
58            return False
59
60class CredoActionButtonStudent(ManageActionButton):
61    grok.order(8)
62    grok.context(INigeriaOnlinePayment)
63    grok.view(NOPDPStudent)
64    grok.require('waeup.payStudent')
65    icon = 'actionicon_pay.png'
66    text = _('Pay via Etranzact Credo')
67    target = 'goto_credo'
68
69    @property
70    def target_url(self):
71        if not credo_module_activated(
72            self.context.student.current_session, self.context):
73            return ''
74        if self.context.p_state != 'unpaid':
75            return ''
76        return self.view.url(self.view.context, self.target)
77
78class CredoActionButtonApplicant(CredoActionButtonStudent):
79    grok.context(INigeriaOnlinePayment)
80    grok.require('waeup.payApplicant')
81    grok.view(NOPDPApplicant)
82
83    @property
84    def target_url(self):
85        if not credo_module_activated(
86            self.context.__parent__.__parent__.year, self.context):
87            return ''
88        if self.context.p_state != 'unpaid':
89            return ''
90        return self.view.url(self.view.context, self.target)
91
92class CredoVerifyActionButtonStudent(ManageActionButton):
93    grok.order(9)
94    grok.context(INigeriaOnlinePayment)
95    grok.view(NOPDPStudent)
96    grok.require('waeup.payStudent')
97    icon = 'actionicon_call.png'
98    text = _('Requery Etranzact Credo')
99    target = 'requery_credo'
100
101    @property
102    def target_url(self):
103        if not credo_module_activated(
104            self.context.student.current_session, self.context):
105            return ''
106        if self.context.p_state in ('paid', 'waived', 'scholarship', 'failed'):
107            return ''
108        return self.view.url(self.view.context, self.target)
109
110class CredoVerifyActionButtonApplicant(CredoVerifyActionButtonStudent):
111    grok.view(NOPDPApplicant)
112    grok.require('waeup.payApplicant')
113    icon = 'actionicon_call.png'
114    text = _('Requery Etranzact Credo')
115    target = 'requery_credo'
116
117    @property
118    def target_url(self):
119        if not credo_module_activated(
120            self.context.__parent__.__parent__.year, self.context):
121            return ''
122        if self.context.p_state in ('paid', 'waived', 'scholarship', 'failed'):
123            return ''
124        return self.view.url(self.view.context, self.target)
125
126class CredoPageStudent(KofaEditFormPage):
127    """ View which sends a POST request to the Credo payment gateway.
128    """
129    grok.context(INigeriaStudentOnlinePayment)
130    grok.name('goto_credo')
131    grok.template('goto_credo')
132    grok.require('waeup.payStudent')
133    label = _('Pay via Credo')
134    submit_button = _('Pay now')
135
136    host = CREDO_HOST
137    api_public_key = API_PUBLIC_KEY
138    gateway_amt = 0.0 # is being added by Etranzact
139
140    serviceCode = None
141
142    def init_update(self):
143        if self.context.p_state == 'paid':
144            return _("Payment ticket can't be re-sent to Etranzact.")
145        now = datetime.utcnow()
146        if self.context.creation_date.tzinfo is not None:
147            # That's bad. Please store timezone-naive datetimes only!
148            now = self.context.creation_date.tzinfo.localize(now)
149        time_delta = now - self.context.creation_date
150        if time_delta.days > 7:
151            return _("This payment ticket is too old. Please create a new ticket.")
152        self.callbackUrl = self.url(self.context, 'requery_credo')
153        return
154
155    def update(self):
156        if not credo_module_activated(
157            self.context.student.current_session, self.context):
158            self.flash(_('Forbidden'), type='danger')
159            self.redirect(self.url(self.context, '@@index'))
160            return
161        # Already now it becomes an Etranzact payment. We set the net amount
162        # and add the gateway amount.
163        if not self.context.r_company:
164            self.context.net_amt = self.context.amount_auth
165            #self.context.amount_auth += self.gateway_amt
166            #self.context.gateway_amt = self.gateway_amt
167            self.context.r_company = u'etranzact'
168        #self.amount = "%.1f" % (100.0 * self.context.amount_auth)
169        error = self.init_update()
170        self.customer = self.context.student
171        if error:
172            self.flash(error, type='danger')
173            self.redirect(self.url(self.context, '@@index'))
174            return
175        return
176
177    @action(_('Pay now'), validator=NullValidator, style='primary')
178    def pay(self, **data):
179        success, url_or_message = initiate_payment(
180            self.context, self.host, self.callbackUrl,
181            self.api_public_key, self.serviceCode)
182        if success:
183            self.redirect(url_or_message, trusted=True)
184        else:
185            self.flash(url_or_message, type='danger')
186            self.redirect(self.url(self.context, '@@index'))
187        return
188
189class CredoPageApplicant(CredoPageStudent):
190    """ View which sends a POST request to the Credo payment gateway.
191    """
192    grok.require('waeup.payApplicant')
193    grok.context(INigeriaApplicantOnlinePayment)
194
195    def update(self):
196        if not credo_module_activated(
197            self.context.__parent__.__parent__.year, self.context):
198            self.flash(_('Forbidden'), type='danger')
199            self.redirect(self.url(self.context, '@@index'))
200            return
201        # Already now it becomes an Etranzact payment. We set the net amount
202        # and add the gateway amount.
203        if not self.context.r_company:
204            self.context.net_amt = self.context.amount_auth
205            #self.context.amount_auth += self.gateway_amt
206            #self.context.gateway_amt = self.gateway_amt
207            self.context.r_company = u'etranzact'
208        #self.amount = "%.1f" % (100.0 * self.context.amount_auth)
209        error = self.init_update()
210        self.customer = self.context.__parent__
211        if error:
212            self.flash(error, type='danger')
213            self.redirect(self.url(self.context, '@@index'))
214            return
215        return
216
217class CredoVerifyPaymentStatusPageStudent(UtilityView, grok.View):
218    """ Request webservice view for the Etranzact Credo gateway.
219    """
220    grok.context(INigeriaStudentOnlinePayment)
221    grok.name('requery_credo')
222    grok.require('waeup.payStudent')
223
224    host = CREDO_HOST
225    secret_api_key = SECRET_API_KEY
226
227    def update(self):
228        if not credo_module_activated(
229            self.context.student.current_session, self.context):
230            self.flash(_('Forbidden'), type='danger')
231            self.redirect(self.url(self.context, '@@index'))
232            return
233        if self.context.p_state in ('paid', 'waived', 'scholarship', 'failed'):
234            self.flash(_('This ticket has already been processed.'), type='danger')
235            return
236        student = self.context.student
237        #verify = False
238        success, msg, log = query_credo_payment(self.context, self.host, self.secret_api_key)
239        student.writeLogMessage(self, log)
240        if not success:
241            self.flash(msg, type='danger')
242            return
243        write_payments_log(student.student_id, self.context)
244        flashtype, msg, log = self.context.doAfterStudentPayment()
245        if log is not None:
246            student.writeLogMessage(self, log)
247        self.flash(msg, type=flashtype)
248        return
249
250    def render(self):
251        self.redirect(self.url(self.context))
252        return
253
254
255class CredoVerifyPaymentStatusPageApplicant(CredoVerifyPaymentStatusPageStudent):
256    """ Request webservice view for the Etranzact Credo gateway.
257    """
258    grok.context(INigeriaApplicantOnlinePayment)
259    grok.name('requery_credo')
260    grok.require('waeup.payApplicant')
261
262    def update(self):
263        if not credo_module_activated(
264            self.context.__parent__.__parent__.year, self.context):
265            self.flash(_('Forbidden'), type='danger')
266            self.redirect(self.url(self.context, '@@index'))
267            return
268        if self.context.p_state in ('paid', 'waived', 'scholarship', 'failed'):
269            self.flash(_('This ticket has already been processed.'), type='danger')
270            return
271        applicant = self.context.__parent__
272        #verify = False
273        success, msg, log = query_credo_payment(self.context, self.host, self.secret_api_key)
274        applicant.writeLogMessage(self, log)
275        if not success:
276            self.flash(msg, type='danger')
277            return
278        write_payments_log(applicant.applicant_id, self.context)
279        flashtype, msg, log = self.context.doAfterApplicantPayment()
280        if log is not None:
281            applicant.writeLogMessage(self, log)
282        self.flash(msg, type=flashtype)
283        return
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
Note: See TracBrowser for help on using the repository browser.