source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/browser.py @ 13581

Last change on this file since 13581 was 13581, checked in by Henrik Bettermann, 9 years ago

Add buttons and pages to verify CollegePay? payments.

  • Property svn:keywords set to Id
File size: 12.2 KB
Line 
1## $Id: browser.py 13581 2016-01-10 22:06:10Z 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##
18import grok
19from datetime import datetime, timedelta
20from zope.component import getUtility
21from zope.security import checkPermission
22from waeup.kofa.interfaces import IKofaUtils
23from waeup.kofa.utils.helpers import to_timezone
24from waeup.kofa.browser.layout import UtilityView, KofaPage
25from waeup.kofa.browser.viewlets import ManageActionButton
26from waeup.kofa.students.interfaces import IStudentsUtils
27from waeup.kofa.students.browser import OnlinePaymentDisplayFormPage as OPDPStudent
28from waeup.kofa.applicants.browser import OnlinePaymentDisplayFormPage as OPDPApplicant
29from kofacustom.nigeria.interswitch.helpers import (
30    query_interswitch, write_payments_log)
31from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
32from kofacustom.nigeria.students.interfaces import INigeriaStudentOnlinePayment
33from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment
34from kofacustom.nigeria.interfaces import MessageFactory as _
35
36# Buttons
37
38class InterswitchActionButtonStudent(ManageActionButton):
39    grok.order(1)
40    grok.context(INigeriaOnlinePayment)
41    grok.view(OPDPStudent)
42    grok.require('waeup.payStudent')
43    icon = 'actionicon_pay.png'
44    text = _('CollegePAY')
45    target = 'goto_interswitch'
46
47    @property
48    def target_url(self):
49        if self.context.p_state != 'unpaid':
50            return ''
51        return self.view.url(self.view.context, self.target)
52
53class InterswitchActionButtonApplicant(InterswitchActionButtonStudent):
54    grok.view(OPDPApplicant)
55    grok.require('waeup.payApplicant')
56
57class InterswitchRequestWebserviceActionButtonStudent(ManageActionButton):
58    grok.order(2)
59    grok.context(INigeriaOnlinePayment)
60    grok.view(OPDPStudent)
61    grok.require('waeup.payStudent')
62    icon = 'actionicon_call.png'
63    text = _('Requery CollegePAY')
64    target = 'request_webservice'
65
66    @property
67    def target_url(self):
68        if self.context.p_state in ('paid', 'waived'):
69            return ''
70        return self.view.url(self.view.context, self.target)
71
72class InterswitchRequestWebserviceActionButtonApplicant(
73    InterswitchRequestWebserviceActionButtonStudent):
74    grok.view(OPDPApplicant)
75    grok.require('waeup.payApplicant')
76
77class InterswitchVerifyWebserviceActionButtonStudent(ManageActionButton):
78    grok.order(3)
79    grok.context(INigeriaOnlinePayment)
80    grok.view(OPDPStudent)
81    grok.require('waeup.manageStudent')
82    icon = 'actionicon_call.png'
83    text = _('Verify Payment')
84    target = 'verify_payment'
85
86    @property
87    def target_url(self):
88        if self.context.p_state != 'paid':
89            return ''
90        return self.view.url(self.view.context, self.target)
91
92class InterswitchVerifyWebserviceActionButtonApplicant(
93    InterswitchVerifyWebserviceActionButtonStudent):
94    grok.view(OPDPApplicant)
95    grok.require('waeup.manageApplication')
96
97
98# Webservice request views
99
100class InterswitchPaymentRequestWebservicePageStudent(UtilityView, grok.View):
101    """ Request webservice view for the CollegePAY gateway
102    """
103    grok.context(INigeriaStudentOnlinePayment)
104    grok.name('request_webservice')
105    grok.require('waeup.payStudent')
106
107    product_id = None
108    gateway_host = None
109    gateway_url = None
110    https = True
111    mac = None
112
113    def update(self):
114        if self.context.p_state in ('paid', 'waived'):
115            self.flash(_('This ticket has already been paid.'), type='danger')
116            return
117        student = self.context.student
118        success, msg, log = query_interswitch(
119            self.context, self.product_id,
120            self.gateway_host, self.gateway_url,
121            self.https, self.mac)
122        student.writeLogMessage(self, log)
123        if not success:
124            self.flash(msg, type='danger')
125            return
126        write_payments_log(student.student_id, self.context)
127        flashtype, msg, log = self.context.doAfterStudentPayment()
128        if log is not None:
129            student.writeLogMessage(self, log)
130        self.flash(msg, type=flashtype)
131        return
132
133    def render(self):
134        self.redirect(self.url(self.context, '@@index'))
135        return
136
137class InterswitchPaymentRequestWebservicePageApplicant(UtilityView, grok.View):
138    """ Request webservice view for the CollegePAY gateway
139    """
140    grok.context(INigeriaApplicantOnlinePayment)
141    grok.name('request_webservice')
142    grok.require('waeup.payApplicant')
143
144    product_id = None
145    gateway_host = None
146    gateway_url = None
147    https = True
148    mac = None
149
150    def update(self):
151        if self.context.p_state == 'paid':
152            self.flash(_('This ticket has already been paid.'), type='danger')
153            return
154        applicant = self.context.__parent__
155        success, msg, log = query_interswitch(
156            self.context, self.product_id,
157            self.gateway_host, self.gateway_url,
158            self.https, self.mac)
159        applicant.writeLogMessage(self, log)
160        if not success:
161            self.flash(msg, type='danger')
162            return
163        write_payments_log(applicant.applicant_id, self.context)
164        flashtype, msg, log = self.context.doAfterApplicantPayment()
165        if log is not None:
166            applicant.writeLogMessage(self, log)
167        self.flash(msg, type=flashtype)
168        return
169
170    def render(self):
171        self.redirect(self.url(self.context, '@@index'))
172        return
173
174class InterswitchPaymentVerifyWebservicePageStudent(UtilityView, grok.View):
175    """ Verify payment view for the CollegePAY gateway
176    """
177    grok.context(INigeriaStudentOnlinePayment)
178    grok.name('verify_payment')
179    grok.require('waeup.manageStudent')
180
181    product_id = None
182    gateway_host = None
183    gateway_url = None
184    https = True
185    mac = None
186
187    def update(self):
188        if self.context.p_state  != 'paid':
189            self.flash(_('This ticket has not been paid.'), type='danger')
190            return
191        student = self.context.student
192        success, msg, log = query_interswitch(
193            self.context, self.product_id,
194            self.gateway_host, self.gateway_url,
195            self.https, self.mac)
196        student.writeLogMessage(self, log)
197        if not success:
198            self.flash(msg, type='danger')
199            return
200        self.flash(msg)
201        return
202
203    def render(self):
204        self.redirect(self.url(self.context, '@@index'))
205        return
206
207class InterswitchPaymentVerifyWebservicePageApplicant(UtilityView, grok.View):
208    """ Verify payment view for the CollegePAY gateway
209    """
210    grok.context(INigeriaApplicantOnlinePayment)
211    grok.name('verify_payment')
212    grok.require('waeup.manageApplication')
213
214    product_id = None
215    gateway_host = None
216    gateway_url = None
217    https = True
218    mac = None
219
220    def update(self):
221        if self.context.p_state != 'paid':
222            self.flash(_('This ticket has not been paid.'), type='danger')
223            return
224        applicant = self.context.__parent__
225        success, msg, log = query_interswitch(
226            self.context, self.product_id,
227            self.gateway_host, self.gateway_url,
228            self.https, self.mac)
229        applicant.writeLogMessage(self, log)
230        if not success:
231            self.flash(msg, type='danger')
232            return
233        self.flash(msg)
234        return
235
236    def render(self):
237        self.redirect(self.url(self.context, '@@index'))
238        return
239
240# Forwarding pages
241
242class InterswitchPageStudent(KofaPage):
243    """ View which sends a POST request to the Interswitch
244    CollegePAY payment gateway.
245    """
246    grok.context(INigeriaOnlinePayment)
247    grok.name('goto_interswitch')
248    grok.template('student_goto_interswitch')
249    grok.require('waeup.payStudent')
250    label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
251    submit_button = _('Submit')
252
253    action = None
254    site_name = None
255    currency = None
256    pay_item_id = None
257    product_id = None
258    xml_data = None
259    hashvalue = None
260
261    def init_update(self):
262        if self.context.p_state == 'paid':
263            return _("Payment ticket can't be re-sent to CollegePAY.")
264        now = datetime.utcnow()
265        if self.context.creation_date.tzinfo is not None:
266            # That's bad. Please store timezone-naive datetimes only!
267            now = self.context.creation_date.tzinfo.localize(now)
268        time_delta = now - self.context.creation_date
269        if time_delta.days > 7:
270            return _("This payment ticket is too old. Please create a new ticket.")
271        student = self.context.student
272        certificate = getattr(student['studycourse'],'certificate',None)
273        if certificate is None:
274            return _("Study course data are incomplete.")
275        kofa_utils = getUtility(IKofaUtils)
276        student_utils = getUtility(IStudentsUtils)
277        if student_utils.samePaymentMade(student, self.context.p_category,
278            self.context.p_item, self.context.p_session):
279            return _("This type of payment has already been made.")
280        self.amount_auth = int(100 * self.context.amount_auth)
281        xmldict = {}
282        if certificate is not None:
283            xmldict['department'] = certificate.__parent__.__parent__.code
284            xmldict['faculty'] = certificate.__parent__.__parent__.__parent__.code
285        else:
286            xmldict['department'] = None
287            xmldict['faculty'] = None
288        self.category = self.context.category
289        tz = kofa_utils.tzinfo
290        self.local_date_time = to_timezone(
291            self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
292        self.site_redirect_url = self.url(self.context, 'request_webservice')
293        self.student = student
294        self.xmldict = xmldict
295        return
296
297    def update(self):
298        error = self.init_update()
299        if error:
300            self.flash(error, type='danger')
301            self.redirect(self.url(self.context, '@@index'))
302        return
303
304class InterswitchPageApplicant(KofaPage):
305    """ View which sends a POST request to the Interswitch
306    CollegePAY payment gateway.
307    """
308    grok.context(INigeriaApplicantOnlinePayment)
309    grok.require('waeup.payApplicant')
310    grok.template('applicant_goto_interswitch')
311    grok.name('goto_interswitch')
312    label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
313    submit_button = _('Submit')
314    hashvalue = None
315
316    action = None
317    site_name = None
318    currency = None
319    pay_item_id = None
320    product_id = None
321    xml_data = None
322
323    def init_update(self):
324        if self.context.p_state != 'unpaid':
325            return _("Payment ticket can't be re-sent to CollegePAY.")
326        if self.context.__parent__.__parent__.expired \
327            and self.context.__parent__.__parent__.strict_deadline:
328            return _("Payment ticket can't be send to CollegePAY. "
329                     "Application period has expired.")
330        tz = getUtility(IKofaUtils).tzinfo
331        time_delta = datetime.utcnow() - self.context.creation_date
332        if time_delta.days > 7:
333            return _("This payment ticket is too old. Please create a new ticket.")
334        self.applicant = self.context.__parent__
335        self.amount_auth = int(100 * self.context.amount_auth)
336        self.category = self.context.category
337        tz = getUtility(IKofaUtils).tzinfo
338        self.local_date_time = to_timezone(
339            self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
340        self.site_redirect_url = self.url(self.context, 'request_webservice')
341        return
342
343    def update(self):
344        error = self.init_update()
345        if error:
346            self.flash(error, type='danger')
347            self.redirect(self.url(self.context, '@@index'))
348        return
Note: See TracBrowser for help on using the repository browser.