source: main/kofacustom.nigeria/branches/uli-paypal/src/kofacustom/nigeria/paypal/applicantsbrowser.py @ 17952

Last change on this file since 17952 was 17241, checked in by Henrik Bettermann, 23 months ago

Ease customization.

File size: 8.0 KB
Line 
1## $Id: browser.py 14759 2017-08-03 09:09:54Z 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, queryUtility
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 waeup.kofa.applicants.browser import OnlinePaymentDisplayFormPage as OPDPApplicant
28#from kofacustom.nigeria.remita.helpers import (
29#    get_JSON_POST_response, query_remita, write_payments_log)
30from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
31from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment
32from kofacustom.nigeria.interfaces import MessageFactory as _
33from kofacustom.nigeria.paypal import module_activated, Amount, PurchaseUnit
34from kofacustom.nigeria.paypal.interfaces import IPaypalConfig
35from kofacustom.nigeria.paypal.rest import create_order, capture_order
36
37
38# grok.templatedir('browser_templates')
39
40
41# Buttons
42
43
44class PaypalActionButtonApplicant(ManageActionButton):
45    grok.order(1)
46    grok.context(INigeriaOnlinePayment)
47    grok.view(OPDPApplicant)
48    grok.require('waeup.payApplicant')
49    icon = 'actionicon_pay.png'
50    text = _('Pay via Paypal')
51    target = 'goto_paypal'
52
53    @property
54    def target_url(self):
55        # import pdb; pdb.set_trace()
56        if not module_activated(
57            self.context.__parent__.__parent__.year, self.context):
58            return ''
59        if self.context.p_state != 'unpaid':
60            return ''
61        return self.view.url(self.view.context, self.target)
62
63
64class PaypalRequestPaymentStatusActionButtonApplicant(ManageActionButton):
65    grok.order(2)
66    grok.context(INigeriaOnlinePayment)
67    grok.view(OPDPApplicant)
68    grok.require('waeup.payApplicant')
69    icon = 'actionicon_call.png'
70    text = _('Requery Paypal Payment Status')
71    target = 'capture_paypal_payment'
72
73    @property
74    def target_url(self):
75        if not module_activated(
76            self.context.__parent__.__parent__.year, self.context):
77            return ''
78        if self.context.p_state in ('paid', 'waived', 'scholarship'):
79            return ''
80        return self.view.url(self.view.context, self.target)
81
82
83class PaypalVerifyPaymentStatusActionButtonApplicant(ManageActionButton):
84    grok.order(3)
85    grok.context(INigeriaOnlinePayment)
86    grok.view(OPDPApplicant)
87    grok.require('waeup.manageApplication')
88    icon = 'actionicon_call.png'
89    text = _('Verify Paypal Payment Status')
90    target = 'verify_payment_status'
91
92    @property
93    def target_url(self):
94        if not module_activated(
95            self.context.__parent__.__parent__.year, self.context):
96            return ''
97        if self.context.p_state != 'paid' \
98            or self.context.r_company != u'paypal':
99            return ''
100        return self.view.url(self.view.context, self.target)
101
102
103# Webservice request views
104
105
106class PaypalRequestPaymentStatusPageApplicant(UtilityView, grok.View):
107    """ Capture order created before
108    """
109    grok.context(INigeriaApplicantOnlinePayment)
110    grok.name('capture_paypal_payment')
111    grok.require('waeup.payApplicant')
112
113
114    def update(self):
115        if not module_activated(
116            self.context.__parent__.__parent__.year, self.context):
117            self.flash(_('Forbidden'), type='danger')
118            self.redirect(self.url(self.context, '@@index'))
119            return
120        if self.context.p_state in ('paid', 'waived', 'scholarship'):
121            self.flash(_('This ticket has already been paid.'), type='danger')
122            return
123        response = capture_order(self.context.r_pay_reference)
124        if response.get("status", None) == "COMPLETED":
125            self.context.p_state = u'paid'
126        if not response:
127            self.flash(_('Paypal Order ID not found.'), type='danger')
128            return
129
130    def render(self):
131        self.redirect(self.url(self.context, '@@index'))
132        return
133
134
135# Forwarding pages
136
137class PaypalPageApplicant(KofaPage):
138    """ Create Paypal Order (and send user to paypal)
139    """
140    grok.context(INigeriaApplicantOnlinePayment)
141    grok.name('goto_paypal')
142    grok.require('waeup.payApplicant')
143    label = _('Pay via Paypal')
144    submit_button = _('Pay now')
145
146    # Nigerian Naira would be "NGN" but is not supported with
147    # most paypal accounts
148    currency_code = 'USD'
149
150    @property
151    def action(self):
152        return self.context.r_payment_link
153
154    def create_paypal_order(self, currency_code):
155        if self.context.r_pay_reference or self.context.p_state == 'paid':
156            return _("Payment ticket can't be re-sent to Paypal.")
157        if self.context.r_company and self.context.r_company != 'paypal':
158            return _("Payment ticket has been used for another payment gateway.")
159        now = datetime.utcnow()
160        if self.context.creation_date.tzinfo is not None:
161            # That's bad. Please store timezone-naive datetimes only!
162            now = self.context.creation_date.tzinfo.localize(now)
163        time_delta = now - self.context.creation_date
164        if time_delta.days > 7:
165            return _("This payment ticket is too old. Please create a new ticket.")
166        # The success url...
167        self.responseurl = self.url(self.context, 'capture_paypal_payment')
168        amount = Amount(value=self.context.amount_auth, currency_code=self.currency_code)
169        purchase_units = [
170                PurchaseUnit(description=self.context.p_id, amount=amount)
171                ]
172        order_id, payment_link, request_id, data = create_order(
173                purchase_units,
174                self.responseurl,         # success/authorized url
175                self.url(self.context),   # cancel/failed url
176                notify_url="https://h9.waeup.org/ipn"
177                )
178        if not order_id:  # an error happened...
179            err_msg = " ".join([x["description"] for x in data["details"]])
180            return _("Paypal order failed: %s") % err_msg
181        self.context.r_payment_link = payment_link
182        self.context.r_pay_reference = order_id
183        self.context.r_company = u'paypal'
184        self.customer = self.context.__parent__
185        self.customer.writeLogMessage(self, "Paypal Order Created: %s" % (
186            order_id))
187        return
188
189    def update(self):
190        if not module_activated(
191            self.context.__parent__.__parent__.year, self.context):
192            self.flash(_('Forbidden'), type='danger')
193            self.redirect(self.url(self.context, '@@index'))
194            return
195        self.paypal_error = u''
196        if not self.context.r_payment_link:
197            self.paypal_error = self.create_paypal_order(self.currency_code)
198        if self.paypal_error:
199            self.flash(error, type='danger')
200            self.redirect(self.url(self.context, '@@index'))
201            return
202        # Payment created - it must now be
203        # - authorized (by user)
204        # - captured (by us, afterwards)
205        if not self.context.r_company:
206            self.context.r_company = u'paypal'
207        return
208
209    def render(self):
210        if self.context.r_payment_link and self.context.p_state != 'paid':
211            self.redirect(self.context.r_payment_link, trusted=True)
212            return
213        self.redirect(self.url(self.context, '@@index'))
214
Note: See TracBrowser for help on using the repository browser.