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

Last change on this file since 17303 was 17303, checked in by Henrik Bettermann, 20 months ago

Revert order.

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