source: main/kofacustom.lpng/trunk/src/kofacustom/lpng/applicants/browser.py @ 17296

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

Implement Paypal module.

  • Property svn:keywords set to Id
File size: 12.4 KB
RevLine 
[16717]1## $Id: browser.py 17254 2022-12-30 09:25:50Z henrik $
[15614]2##
3## Copyright (C) 2011 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##
18"""UI components for basic applicants and related components.
19"""
20import grok
[16997]21from zope.formlib.textwidgets import BytesDisplayWidget
[17020]22from zope.component import getUtility
[17023]23from hurry.workflow.interfaces import IWorkflowState
[17020]24from waeup.kofa.widgets.datewidget import (
25    FriendlyDateDisplayWidget,
26    FriendlyDatetimeDisplayWidget)
[16997]27from waeup.kofa.applicants.pdf import PDFApplicationSlip
[17254]28from waeup.kofa.browser.layout import KofaEditFormPage, KofaPage, action, NullValidator
[15614]29from waeup.kofa.applicants.browser import (
[16997]30    ApplicantRegistrationPage, ApplicantsContainerPage,
31    ApplicantDisplayFormPage,
32    ApplicantManageFormPage,
[17019]33    ApplicantEditFormPage,
[17020]34    BalancePaymentAddFormPage,
35    ExportPDFPaymentSlipPage,
[17201]36    ApplicantBaseDisplayFormPage,
37    ExportJobContainerJobStart)
[17023]38from waeup.kofa.applicants.workflow import (
39    INITIALIZED, STARTED, PAID, SUBMITTED,
40    ADMITTED, NOT_ADMITTED, CREATED, PROCESSED)
[17020]41from waeup.kofa.students.interfaces import IStudentsUtils
[17023]42from waeup.kofa.applicants.interfaces import (
43    IApplicantOnlinePayment, IApplicantsUtils)
[17020]44from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment
[17216]45from kofacustom.nigeria.applicants.browser import (
46    NigeriaExportPDFPaymentSlipPage, NigeriaOnlinePaymentDisplayFormPage)
[16983]47from kofacustom.lpng.applicants.interfaces import (
[16997]48    ICustomApplicant,
[16718]49    ICustomApplicantOnlinePayment,
[17013]50    ICustomApplicantEdit,
[17091]51    IPollingUnit,
52    STATES, LGAS, WARDS, PUNITS
[16718]53    )
[16983]54from kofacustom.lpng.interfaces import MessageFactory as _
[15614]55
[17201]56
57class CustomExportJobContainerJobStart(ExportJobContainerJobStart):
58    """View that starts three export jobs, one for applicants, a second
59    one for applicant payments and a third for referee reports.
60    """
61
62    EXPORTER_LIST = ('applicants',
63                   'applicantpayments',
64                   )
[16997]65       
66class CustomApplicantDisplayFormPage(ApplicantDisplayFormPage):
67    """A display view for applicant data.
68    """
69
70    @property
[17091]71    def render_punit(self):
72        if self.context.punit:
73            punit = self.context.punit.split('_')
[17216]74            return ' -> '.join([STATES[punit[0]],
[17091]75                    LGAS['_'.join(punit[:2])],
76                    WARDS['_'.join(punit[:3])] ,
77                    PUNITS['_'.join(punit[:4])]
78                   ])
79        return
80
81    @property
[16997]82    def form_fields(self):
[17091]83        form_fields = grok.AutoFields(
84            ICustomApplicant).omit('locked', 'suspended', 'federalstate',
85                                   'lga', 'ward', 'punit')
[16997]86        form_fields['perm_address'].custom_widget = BytesDisplayWidget
[17091]87        #form_fields['notice'].custom_widget = BytesDisplayWidget
[16997]88        if not getattr(self.context, 'student_id'):
89            form_fields = form_fields.omit('student_id')
90        return form_fields
91
92class CustomPDFApplicationSlip(PDFApplicationSlip):
93
94    @property
95    def form_fields(self):
96        form_fields = grok.AutoFields(ICustomApplicant)
97        if not getattr(self.context, 'student_id'):
98            form_fields = form_fields.omit('student_id')
99        return form_fields
100
101class CustomApplicantManageFormPage(ApplicantManageFormPage):
102    """A full edit view for applicant data.
103    """
104
105    @property
[17023]106    def display_actions(self):
107        actions = [[_('Save'), _('Finally Submit')],
108                   [
109                    #_('Add online payment ticket'),
110                    _('Add balance payment ticket'),
111                    _('Remove selected tickets')
112                   ]]
113        applicants_utils = getUtility(IApplicantsUtils)
114        if self.context.state not in applicants_utils.BALANCE_PAYMENT_STATES:
115            actions[1].pop(1)
116        return actions
117
118    @property
[16997]119    def form_fields(self):
[17091]120        form_fields = grok.AutoFields(ICustomApplicant).omit(
121            'federalstate', 'lga', 'ward', 'punit')
[16997]122        if not getattr(self.context, 'student_id'):
123            form_fields = form_fields.omit('student_id')
124        form_fields['applicant_id'].for_display = True
125        return form_fields
126
127class CustomApplicantEditFormPage(ApplicantEditFormPage):
[16718]128    """An applicant-centered edit view for applicant data.
129    """
130
131    def unremovable(self, ticket):
132        return True
133
[16997]134    @property
[17023]135    def display_actions(self):
136        state = IWorkflowState(self.context).getState()
137        actions = [[_('Save')],
138                   [
139                    #_('Remove selected tickets')
140                   ]]
141        if state == STARTED:
[17216]142            actions = [[_('Save'),
[17225]143                        _('Save and Make Donation')],
[17023]144                [
145                 #_('Add online payment ticket'),
146                 #_('Remove selected tickets')
147                ]]
148        elif self.context.special and state == PAID:
149            actions = [[_('Save'), _('Finally Submit')],
150                [
151                 #_('Add online payment ticket'),
152                 #_('Remove selected tickets')
153                ]]
154        elif state == PAID:
155            actions = [[_('Save'), _('Finally Submit')],
156                [
157                 #_('Remove selected tickets')
158                ]]
159        applicants_utils = getUtility(IApplicantsUtils)
160        if self.context.state in applicants_utils.BALANCE_PAYMENT_STATES:
[17190]161            actions[1].append(_('Make Donation'))
162            #actions[1].append(_('Make Donation via USSD'))
[17023]163        return actions
164
165    @property
[16997]166    def form_fields(self):
[17013]167        form_fields = grok.AutoFields(ICustomApplicantEdit)
[17091]168        form_fields = form_fields.omit('locked', 'suspended', 'federalstate',
169                                       'lga', 'ward', 'punit')
[16997]170        if not getattr(self.context, 'student_id'):
171            form_fields = form_fields.omit('student_id')
172        form_fields['applicant_id'].for_display = True
173        form_fields['reg_number'].for_display = True
174        return form_fields
[17190]175
176    @action(_('Save'), style='primary')
177    def save(self, **data):
178        if self.upload_success is False:  # False is not None!
179            # Error during image upload. Ignore other values.
180            return
[17225]181        if not self.request.form.get('confirm_passport', False):
182            self.flash(_('Please tick the checkbox above the save buttons.'))
183            return
[17190]184        self.applyData(self.context, **data)
185        self.flash(_('Form has been saved.'))
186        return
187
188    @action(_('Add online payment ticket'), style='primary')
189    def addPaymentTicket(self, **data):
[17225]190        self.redirect(self.url(self.context, 'addafp'))
[17190]191        return
192
193    @action(_('Make Donation'), style='primary')
194    def addBalancePaymentTicket(self, **data):
[17225]195        self.redirect(self.url(self.context, 'addbp'))
[17190]196        return
197
[17225]198    @action(_('Save and Make Donation'), style='primary')
199    def saveAndDonate(self, **data):
[17191]200        if self.upload_success is False:  # False is not None!
201            # Error during image upload. Ignore other values.
202            return
[17225]203        if not self.request.form.get('confirm_passport', False):
204            self.flash(_('Please tick the checkbox above the save buttons.'))
205            return
[17191]206        self.applyData(self.context, **data)
[17225]207        self.redirect(self.url(self.context, 'addbp'))
[17190]208        return
[17019]209       
210class CustomBalancePaymentAddFormPage(BalancePaymentAddFormPage):
211    """ Page to add an online payment which can balance s previous session
212    payment.
213    """
214    grok.require('waeup.payApplicant')
[17020]215   
[17254]216    @action(_('Create ticket'), style='primary')
217    def createTicket(self, **data):
218        p_category = data['p_category']
219        form = self.request.form
220        p_option = form.get('form.p_option', None)
221        balance_amount = data.get('balance_amount', None)
222        applicants_utils = getUtility(IApplicantsUtils)
223        error, payment = applicants_utils.setBalanceDetails(
224            self.context, p_category, balance_amount)
225        if error is not None:
226            self.flash(error, type="danger")
227            return
228        if p_option:
229            payment.p_option = p_option
230            payment.p_currency = p_option
231        self.context[payment.p_id] = payment
232        self.flash(_('Payment ticket created.'))
233        self.context.writeLogMessage(self,'added: %s' % payment.p_id)
234        self.redirect(self.url(payment))
235        return
236
237    @action(_('Cancel'), validator=NullValidator)
238    def cancel(self, **data):
239        self.redirect(self.url(self.context))
240
[17020]241class CustomApplicantBaseDisplayFormPage(ApplicantBaseDisplayFormPage):
[16997]242
[17020]243    @property
244    def form_fields(self):
245        form_fields = grok.AutoFields(ICustomApplicant).select(
246            'applicant_id', 'reg_number', 'email')
247        return form_fields
248
[17216]249class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
250    """ Page to view an online payment ticket
251    """
252    form_fields = grok.AutoFields(INigeriaApplicantOnlinePayment).omit('ac',
253        'provider_amt', 'gateway_amt', 'thirdparty_amt',
[17228]254        'p_item', 'display_item', 'p_session', 'p_split_data')
[17216]255    form_fields[
256        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
257    form_fields[
258        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
259
[17020]260class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
261    """Deliver a PDF slip of the context.
262    """
263    # use IApplicantOnlinePayment alternativly
264    form_fields = grok.AutoFields(INigeriaApplicantOnlinePayment).omit(
[17228]265        'p_item', 'p_option', 'p_combi', 'display_item', 'p_session',
266        'thirdparty_amt', 'p_split_data')
[17020]267    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
268    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
269
270    def render(self):
271        if self.payment_slip_download_warning:
272            self.flash(self.payment_slip_download_warning, type='danger')
273            self.redirect(self.url(self.context))
274            return
275        applicantview = CustomApplicantBaseDisplayFormPage(self.context.__parent__,
276            self.request)
277        students_utils = getUtility(IStudentsUtils)
278        return students_utils.renderPDF(self,'payment_slip.pdf',
279            self.context.__parent__, applicantview, note=self.note,
[17091]280            omit_fields=())
281
282class PunitFormPage(KofaEditFormPage):
283    """
284    """
285    grok.context(ICustomApplicant)
286    grok.require('waeup.handleApplication')
287    grok.name('punitformpage')
288    form_fields = grok.AutoFields(IPollingUnit)
289    grok.template('puniteditpage')
290    label = _('Locate polling unit')
291    pnav = 3
292
[17175]293    @action(_('Save'), style='invisible')
[17091]294    def save(self, **data):
295        changed_fields = self.applyData(self.context, **data)
296        # Turn list of lists into single list
297        if changed_fields:
298            changed_fields = reduce(lambda x, y: x+y, changed_fields.values())
299        if 'federalstate' in changed_fields:
300            # Clear other form fields
301            self.context.lga = self.context.ward = self.context.punit = None
302            self.flash(_('Federal State has been saved.'))
303            return         
304        if 'lga' in changed_fields:
305            # Clear other form fields
306            self.context.ward = self.context.punit = None
307            self.flash(_('LGA has been saved.'))
308            return         
309        if 'ward' in changed_fields:
310            # Clear other form fields
311            self.context.punit = None
312            self.flash(_('Ward has been saved.'))
313            return
314        if 'punit' in changed_fields and self.context.punit:
315            self.flash(_('Polling Unit has been successfully saved.'))
316            self.redirect(self.url(self.context))
[17190]317        return
318
319class USSDInfoPage(KofaPage):
320    """
321    """
[17216]322    grok.context(ICustomApplicantOnlinePayment)
[17190]323    grok.require('waeup.handleApplication')
324    grok.name('ussdinfo')
[17216]325    label = _('Pay via USSD')
[17190]326    grok.template('ussdinfo')
327    pnav = 3
Note: See TracBrowser for help on using the repository browser.