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

Last change on this file since 13478 was 13478, checked in by uli, 9 years ago

More concise fix of the TZ problem.

  • There is no need for try-except. Instead we can properly query the circumstances that lead to TypeError?.
  • There is no need to get the utils tzinfo. In case we get a timezone-aware datetime, there is already a timezone available. We should use this timezone then, to ease calculations. Beside this we must take into account the possibility, that local timezone is None.

The new implementaion addresses these problems.

  • Property svn:keywords set to Id
File size: 9.5 KB
Line 
1## $Id: browser.py 13478 2015-11-18 15:55:26Z uli $
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 waeup.kofa.interfaces import IKofaUtils
22from waeup.kofa.utils.helpers import to_timezone
23from waeup.kofa.browser.layout import UtilityView, KofaPage
24from waeup.kofa.browser.viewlets import ManageActionButton
25from waeup.kofa.students.interfaces import IStudentsUtils
26from waeup.kofa.students.browser import OnlinePaymentDisplayFormPage as OPDPStudent
27from waeup.kofa.applicants.browser import OnlinePaymentDisplayFormPage as OPDPApplicant
28from kofacustom.nigeria.interswitch.helpers import (
29    query_interswitch, write_payments_log)
30from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
31from kofacustom.nigeria.students.interfaces import INigeriaStudentOnlinePayment
32from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment
33from kofacustom.nigeria.interfaces import MessageFactory as _
34
35class InterswitchActionButtonStudent(ManageActionButton):
36    grok.order(1)
37    grok.context(INigeriaOnlinePayment)
38    grok.view(OPDPStudent)
39    grok.require('waeup.payStudent')
40    icon = 'actionicon_pay.png'
41    text = _('CollegePAY')
42    target = 'goto_interswitch'
43
44    @property
45    def target_url(self):
46        if self.context.p_state != 'unpaid':
47            return ''
48        return self.view.url(self.view.context, self.target)
49
50class InterswitchActionButtonApplicant(InterswitchActionButtonStudent):
51    grok.view(OPDPApplicant)
52    grok.require('waeup.payApplicant')
53
54class InterswitchRequestWebserviceActionButtonStudent(ManageActionButton):
55    grok.order(2)
56    grok.context(INigeriaOnlinePayment)
57    grok.view(OPDPStudent)
58    grok.require('waeup.payStudent')
59    icon = 'actionicon_call.png'
60    text = _('Requery CollegePAY')
61    target = 'request_webservice'
62
63    @property
64    def target_url(self):
65        if self.context.p_state in ('paid', 'waived'):
66            return ''
67        return self.view.url(self.view.context, self.target)
68
69class InterswitchRequestWebserviceActionButtonApplicant(
70    InterswitchRequestWebserviceActionButtonStudent):
71    grok.view(OPDPApplicant)
72    grok.require('waeup.payApplicant')
73
74class InterswitchPaymentRequestWebservicePageStudent(UtilityView, grok.View):
75    """ Request webservice view for the CollegePAY gateway
76    """
77    grok.context(INigeriaStudentOnlinePayment)
78    grok.name('request_webservice')
79    grok.require('waeup.payStudent')
80
81    product_id = None
82    gateway_host = None
83    gateway_url = None
84    https = True
85    mac = None
86
87    def update(self):
88        if self.context.p_state in ('paid', 'waived'):
89            self.flash(_('This ticket has already been paid.'), type='warning')
90            return
91        student = self.context.student
92        success, msg, log = query_interswitch(
93            self.context, self.product_id,
94            self.gateway_host, self.gateway_url,
95            self.https, self.mac)
96        student.writeLogMessage(self, log)
97        if not success:
98            self.flash(msg, type='danger')
99            return
100        write_payments_log(student.student_id, self.context)
101        flashtype, msg, log = self.context.doAfterStudentPayment()
102        if log is not None:
103            student.writeLogMessage(self, log)
104        self.flash(msg, type=flashtype)
105        return
106
107    def render(self):
108        self.redirect(self.url(self.context, '@@index'))
109        return
110
111class InterswitchPaymentRequestWebservicePageApplicant(UtilityView, grok.View):
112    """ Request webservice view for the CollegePAY gateway
113    """
114    grok.context(INigeriaApplicantOnlinePayment)
115    grok.name('request_webservice')
116    grok.require('waeup.payApplicant')
117
118    product_id = None
119    gateway_host = None
120    gateway_url = None
121    https = True
122    mac = None
123
124    def update(self):
125        if self.context.p_state == 'paid':
126            self.flash(_('This ticket has already been paid.'), type='danger')
127            return
128        applicant = self.context.__parent__
129        success, msg, log = query_interswitch(
130            self.context, self.product_id,
131            self.gateway_host, self.gateway_url,
132            self.https, self.mac)
133        applicant.writeLogMessage(self, log)
134        if not success:
135            self.flash(msg, type='danger')
136            return
137        write_payments_log(applicant.applicant_id, self.context)
138        flashtype, msg, log = self.context.doAfterApplicantPayment()
139        if log is not None:
140            applicant.writeLogMessage(self, log)
141        self.flash(msg, type=flashtype)
142        return
143
144    def render(self):
145        self.redirect(self.url(self.context, '@@index'))
146        return
147
148class InterswitchPageStudent(KofaPage):
149    """ View which sends a POST request to the Interswitch
150    CollegePAY payment gateway.
151    """
152    grok.context(INigeriaOnlinePayment)
153    grok.name('goto_interswitch')
154    grok.template('student_goto_interswitch')
155    grok.require('waeup.payStudent')
156    label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
157    submit_button = _('Submit')
158
159    action = None
160    site_name = None
161    currency = None
162    pay_item_id = None
163    product_id = None
164    xml_data = None
165    hashvalue = None
166
167    def init_update(self):
168        if self.context.p_state == 'paid':
169            return _("Payment ticket can't be re-sent to CollegePAY.")
170        tz = getUtility(IKofaUtils).tzinfo
171        now = datetime.utcnow()
172        if self.context.creation_date.tzinfo is not None:
173            # That's bad. Please store timezone-naive datetimes only!
174            now = self.context.creation_date.tzinfo.localize(now)
175        time_delta = now - self.context.creation_date
176        if time_delta.days > 7:
177            return _("This payment ticket is too old. Please create a new ticket.")
178        student = self.context.student
179        certificate = getattr(student['studycourse'],'certificate',None)
180        if certificate is None:
181            return _("Study course data are incomplete.")
182        kofa_utils = getUtility(IKofaUtils)
183        student_utils = getUtility(IStudentsUtils)
184        if student_utils.samePaymentMade(student, self.context.p_category,
185            self.context.p_item, self.context.p_session):
186            return _("This type of payment has already been made.")
187        self.amount_auth = int(100 * self.context.amount_auth)
188        xmldict = {}
189        if certificate is not None:
190            xmldict['department'] = certificate.__parent__.__parent__.code
191            xmldict['faculty'] = certificate.__parent__.__parent__.__parent__.code
192        else:
193            xmldict['department'] = None
194            xmldict['faculty'] = None
195        self.category = self.context.category
196        tz = kofa_utils.tzinfo
197        self.local_date_time = to_timezone(
198            self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
199        self.site_redirect_url = self.url(self.context, 'request_webservice')
200        self.student = student
201        self.xmldict = xmldict
202        return
203
204    def update(self):
205        error = self.init_update()
206        if error:
207            self.flash(error, type='danger')
208            self.redirect(self.url(self.context, '@@index'))
209        return
210
211class InterswitchPageApplicant(KofaPage):
212    """ View which sends a POST request to the Interswitch
213    CollegePAY payment gateway.
214    """
215    grok.context(INigeriaApplicantOnlinePayment)
216    grok.require('waeup.payApplicant')
217    grok.template('applicant_goto_interswitch')
218    grok.name('goto_interswitch')
219    label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
220    submit_button = _('Submit')
221    hashvalue = None
222
223    action = None
224    site_name = None
225    currency = None
226    pay_item_id = None
227    product_id = None
228    xml_data = None
229
230    def init_update(self):
231        if self.context.p_state != 'unpaid':
232            return _("Payment ticket can't be re-sent to CollegePAY.")
233        if self.context.__parent__.__parent__.expired \
234            and self.context.__parent__.__parent__.strict_deadline:
235            return _("Payment ticket can't be send to CollegePAY. "
236                     "Application period has expired.")
237        tz = getUtility(IKofaUtils).tzinfo
238        time_delta = datetime.utcnow() - self.context.creation_date
239        if time_delta.days > 7:
240            return _("This payment ticket is too old. Please create a new ticket.")
241        self.applicant = self.context.__parent__
242        self.amount_auth = int(100 * self.context.amount_auth)
243        self.category = self.context.category
244        tz = getUtility(IKofaUtils).tzinfo
245        self.local_date_time = to_timezone(
246            self.context.creation_date, tz).strftime("%Y-%m-%d %H:%M:%S %Z")
247        self.site_redirect_url = self.url(self.context, 'request_webservice')
248        return
249
250    def update(self):
251        error = self.init_update()
252        if error:
253            self.flash(error, type='danger')
254            self.redirect(self.url(self.context, '@@index'))
255        return
Note: See TracBrowser for help on using the repository browser.