source: main/waeup.aaue/trunk/src/waeup/aaue/applicants/browser.py @ 14070

Last change on this file since 14070 was 14057, checked in by Henrik Bettermann, 8 years ago

Use application_slip_notice if set.

  • Property svn:keywords set to Id
File size: 15.9 KB
Line 
1## $Id: browser.py 14057 2016-08-08 05:52:11Z 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
21import os
22from zope.component import getUtility, getAdapter
23from zope.i18n import translate
24from hurry.workflow.interfaces import IWorkflowState
25from waeup.kofa.interfaces import (
26    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
27from zope.formlib.textwidgets import BytesDisplayWidget
28from waeup.kofa.utils.helpers import string_from_bytes, file_size
29from waeup.kofa.applicants.browser import (
30    ApplicantCheckStatusPage, ApplicantBaseDisplayFormPage)
31from waeup.kofa.applicants.workflow import STARTED, PAID
32from waeup.kofa.applicants.viewlets import PDFActionButton
33from waeup.kofa.browser.layout import UtilityView
34from waeup.kofa.students.interfaces import IStudentsUtils
35from waeup.kofa.interfaces import IPDF
36from waeup.kofa.browser.viewlets import ManageActionButton
37from waeup.aaue.interfaces import MessageFactory as _
38from kofacustom.nigeria.applicants.browser import (
39    NigeriaApplicantDisplayFormPage,
40    NigeriaApplicantManageFormPage,
41    NigeriaApplicantEditFormPage,
42    NigeriaPDFApplicationSlip,
43    NigeriaApplicantRegistrationPage,
44    NigeriaExportPDFPaymentSlipPage,
45    )
46from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
47from waeup.aaue.applicants.interfaces import (
48    ICustomUGApplicant,
49    ICustomUGApplicantEdit,
50    ITranscriptApplicant,
51    ICustomApplicant
52    )
53
54UG_OMIT_FIELDS = (
55      'hq_type', 'hq_fname', 'hq_matric_no',
56      'hq_degree', 'hq_school', 'hq_session', 'hq_disc',
57      'hq_type2', 'hq_fname2', 'hq_matric_no2',
58      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
59      'hq_type3', 'hq_fname3', 'hq_matric_no3',
60      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
61      'nysc_year',
62      'nysc_location',
63      'nysc_lga',
64      'employer',
65      'emp_position',
66      'emp_start',
67      'emp_end',
68      'emp_reason',
69      'employer2',
70      'emp2_position',
71      'emp2_start',
72      'emp2_end',
73      'emp2_reason',
74      'former_matric',
75      )
76UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
77    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
78UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
79      'reg_number','alr_fname', 'alr_no', 'alr_date',
80      'alr_results', 'notice')
81UG_OMIT_MANAGE_FIELDS = (
82    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
83UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
84    'student_id',
85    'notice',
86    'jamb_age',
87    'jamb_subjects',
88    'jamb_score',
89    'jamb_reg_number',
90    'aggregate',
91
92    'firstname',
93    'middlename',
94    'lastname',
95    'sex',
96    'lga',
97    'course1',
98    'master_sheet_number',
99    'screening_venue',
100    'screening_score',
101    'screening_date'
102    )
103
104#UG_OMIT_PDF_FIELDS = tuple([
105#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])
106
107#UG_OMIT_PDF_FIELDS += (
108#      'reg_number','alr_fname', 'alr_no', 'alr_date',
109#      'alr_results', 'notice'
110#      )
111
112PG_OMIT_FIELDS = (
113    'fst_sit_fname',
114    'fst_sit_no',
115    'fst_sit_date',
116    'fst_sit_type',
117    'fst_sit_results',
118    'scd_sit_fname',
119    'scd_sit_no',
120    'scd_sit_date',
121    'scd_sit_type',
122    'scd_sit_results',
123    #'programme_type',
124    'jamb_age',
125    'jamb_subjects',
126    'jamb_score',
127    'jamb_reg_number',
128    'aggregate'
129    )
130PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
131    'jamb_subjects_list',) + PG_OMIT_FIELDS
132PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + PG_OMIT_FIELDS + (
133      'reg_number','alr_fname', 'alr_no', 'alr_date',
134      'alr_results', 'notice',
135      'nysc_year',
136      'nysc_location',
137      'nysc_lga',
138      'former_matric',
139      )
140PG_OMIT_MANAGE_FIELDS = (
141    'special_application','jamb_subjects_list',) + PG_OMIT_FIELDS
142PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
143    'student_id',
144    'notice',
145    )
146
147PTEE_OMIT_FIELDS = (
148    'jamb_age',
149    'jamb_subjects',
150    'jamb_score',
151    'jamb_reg_number',
152    'aggregate'
153    )
154PTEE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
155    'jamb_subjects_list',) + PTEE_OMIT_FIELDS
156PTEE_OMIT_PDF_FIELDS = PTEE_OMIT_DISPLAY_FIELDS + PTEE_OMIT_FIELDS + (
157      'reg_number','alr_fname', 'alr_no', 'alr_date',
158      'alr_results', 'notice',
159      'nysc_year',
160      'nysc_location',
161      'nysc_lga',
162      'employer',
163      'emp_position',
164      'emp_start',
165      'emp_end',
166      'emp_reason',
167      'employer2',
168      'emp2_position',
169      'emp2_start',
170      'emp2_end',
171      'emp2_reason',
172      'former_matric',
173    )
174PTEE_OMIT_MANAGE_FIELDS = (
175    'special_application','jamb_subjects_list',) + PTEE_OMIT_FIELDS
176PTEE_OMIT_EDIT_FIELDS = PTEE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
177    'student_id',
178    'notice',
179    )
180
181class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
182    """A display view for applicant data.
183    """
184
185    @property
186    def form_fields(self):
187        if self.target is not None and self.target == 'trans':
188            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
189                'locked', 'suspended')
190            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
191            form_fields['perm_address'].custom_widget = BytesDisplayWidget
192            return form_fields
193        # AAUE is using the same interface for all regular applications.
194        form_fields = grok.AutoFields(ICustomUGApplicant)
195        if self.target is not None and self.target.startswith('pg'):
196            for field in PG_OMIT_DISPLAY_FIELDS:
197                form_fields = form_fields.omit(field)
198        elif self.target is not None and self.target in ('ptee', 'ude'):
199            for field in PTEE_OMIT_DISPLAY_FIELDS:
200                form_fields = form_fields.omit(field)
201        else:
202            for field in UG_OMIT_DISPLAY_FIELDS:
203                form_fields = form_fields.omit(field)
204        form_fields['perm_address'].custom_widget = BytesDisplayWidget
205        form_fields['notice'].custom_widget = BytesDisplayWidget
206        if not getattr(self.context, 'student_id'):
207            form_fields = form_fields.omit('student_id')
208        if not getattr(self.context, 'screening_score'):
209            form_fields = form_fields.omit('screening_score')
210        if not getattr(self.context, 'screening_venue'):
211            form_fields = form_fields.omit('screening_venue')
212        if not getattr(self.context, 'screening_date'):
213            form_fields = form_fields.omit('screening_date')
214        return form_fields
215
216class CustomPDFActionButton(PDFActionButton):
217
218    @property
219    def target_url(self):
220        if self.context.state in ('initialized', 'started', 'paid') \
221            or self.context.special or self.view.target == 'trans':
222            return
223        return self.view.url(self.view.context, self.target)
224
225
226class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
227
228    column_two_fields = ('applicant_id', 'reg_number',
229        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
230    #two_columns_design_fields = [
231    #    'fst_sit_fname', 'fst_sit_no', 'fst_sit_date',
232    #    'fst_sit_type', 'fst_sit_results',
233    #    'scd_sit_fname', 'scd_sit_no', 'scd_sit_date',
234    #    'scd_sit_type', 'scd_sit_results']
235
236    @property
237    def note(self):
238        note = getattr(self.context.__parent__, 'application_slip_notice', None)
239        if note:
240            return '<br /><br />' + note
241        if self.context.sex == 'm':
242            pronoun = 'he'
243        else:
244            pronoun = 'she'
245        return '''
246The applicant has acknowledged that, if discovered at any time that %s does not possess
247any of the qualifications which %s claims %s has obtained, %s will be expelled from the
248University not be re-admitted for the same or any other programme, even if %s has
249upgraded previous and shall qualifications or possess additional qualifications.
250''' % (
251    pronoun, pronoun, pronoun, pronoun, pronoun)
252
253    @property
254    def form_fields(self):
255        # AAUE is using the same interface for all regular applications.
256        form_fields = grok.AutoFields(ICustomUGApplicant)
257        if self.target is not None and self.target.startswith('pg'):
258            for field in PG_OMIT_PDF_FIELDS:
259                form_fields = form_fields.omit(field)
260        elif self.target is not None and self.target in ('ptee', 'ude'):
261            for field in PTEE_OMIT_PDF_FIELDS:
262                form_fields = form_fields.omit(field)
263        else:
264            for field in UG_OMIT_PDF_FIELDS:
265                form_fields = form_fields.omit(field)
266        if not getattr(self.context, 'student_id'):
267            form_fields = form_fields.omit('student_id')
268        if not getattr(self.context, 'screening_score'):
269            form_fields = form_fields.omit('screening_score')
270        if not getattr(self.context, 'screening_venue'):
271            form_fields = form_fields.omit('screening_venue')
272        if not getattr(self.context, 'screening_date'):
273            form_fields = form_fields.omit('screening_date')
274        return form_fields
275
276class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
277    """A full edit view for applicant data.
278    """
279
280    @property
281    def form_fields(self):
282        if self.target is not None and self.target == 'trans':
283            form_fields = grok.AutoFields(ITranscriptApplicant)
284            form_fields['applicant_id'].for_display = True
285            return form_fields
286        # AAUE is using the same interface for all regular applications.
287        form_fields = grok.AutoFields(ICustomUGApplicant)
288        if self.target is not None and self.target.startswith('pg'):
289            for field in PG_OMIT_MANAGE_FIELDS:
290                form_fields = form_fields.omit(field)
291        elif self.target is not None and self.target in ('ptee', 'ude'):
292            for field in PTEE_OMIT_MANAGE_FIELDS:
293                form_fields = form_fields.omit(field)
294        else:
295            for field in UG_OMIT_MANAGE_FIELDS:
296                form_fields = form_fields.omit(field)
297        form_fields['student_id'].for_display = True
298        form_fields['applicant_id'].for_display = True
299        return form_fields
300
301class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
302    """An applicant-centered edit view for applicant data.
303    """
304
305    grok.template('applicanteditpage')
306
307    def unremovable(self, ticket):
308        return True
309
310    # AAUE applicants never see the 'Remove Selected Tickets' button.
311    @property
312    def display_actions(self):
313        state = IWorkflowState(self.context).getState()
314        # If the form is unlocked, applicants are allowed to save the form
315        # and remove unused tickets.
316        actions = [[_('Save')], []]
317        # Only in state started they can also add tickets.
318        if state == STARTED:
319            actions = [[_('Save')],
320                [_('Add online payment ticket')]]
321        # In state paid, they can submit the data and further add tickets
322        # if the application is special.
323        elif self.context.special and state == PAID:
324            actions = [[_('Save'), _('Finally Submit')],
325                [_('Add online payment ticket')]]
326        elif state == PAID:
327            actions = [[_('Save'), _('Finally Submit')], []]
328        return actions
329
330    @property
331    def form_fields(self):
332        if self.target is not None and self.target == 'trans':
333            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
334                'locked', 'suspended')
335            form_fields['applicant_id'].for_display = True
336            return form_fields
337        # AAUE is using the same interface for all regular applications.
338        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
339        if self.target is not None and self.target.startswith('pg'):
340            for field in PG_OMIT_EDIT_FIELDS:
341                form_fields = form_fields.omit(field)
342        elif self.target is not None and self.target in ('ptee', 'ude'):
343            for field in PTEE_OMIT_EDIT_FIELDS:
344                form_fields = form_fields.omit(field)
345        else:
346            for field in UG_OMIT_EDIT_FIELDS:
347                form_fields = form_fields.omit(field)
348        form_fields['applicant_id'].for_display = True
349        form_fields['reg_number'].for_display = True
350        return form_fields
351
352class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
353    """Captcha'd registration page for applicants.
354    """
355
356    def _redirect(self, email, password, applicant_id):
357        # Forward email and credentials to landing page.
358        self.redirect(self.url(self.context, 'registration_complete',
359            data = dict(email=email, password=password,
360            applicant_id=applicant_id)))
361        return
362
363class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
364
365    @property
366    def payment_slip_download_warning(self):
367        return ''
368
369class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
370    """Captcha'd status checking page for applicants.
371    """
372    grok.template('applicantcheckstatus')
373
374class PaymentReceiptActionButton(ManageActionButton):
375    grok.order(8) # This button should always be the last one.
376    grok.context(ICustomApplicant)
377    grok.view(CustomApplicantDisplayFormPage)
378    grok.require('waeup.viewApplication')
379    icon = 'actionicon_pdf.png'
380    text = _('Download screening invitation letter')
381    target = 'screening_invitation.pdf'
382
383    @property
384    def target_url(self):
385        if not self.context.screening_date:
386            return ''
387        return self.view.url(self.view.context, self.target)
388
389class ExportScreeningInvitationLetter(UtilityView, grok.View):
390    """Deliver a slip with only screening data.
391    This form page is available only in AAUE.
392    """
393    grok.context(ICustomApplicant)
394    grok.name('screening_invitation.pdf')
395    grok.require('waeup.viewApplication')
396    prefix = 'form'
397
398    label = u'Screening Invitation Letter'
399
400    form_fields = []
401
402    @property
403    def note(self):
404        if self.context.screening_date:
405            year = self.context.__parent__.year
406            session = '%s/%s' % (year, year + 1)
407            sdate = self.context.screening_date
408            stime = ''
409            if '@' in self.context.screening_date:
410                sdate = self.context.screening_date.split('@')[0].strip()
411                stime = self.context.screening_date.split('@')[1].strip()
412            return """
413<br /><br /><br /><br /><font size='12'>
414Dear %s,
415<br /><br />
416You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
417<br /><br />
418<strong>Date: %s
419<br /><br />
420Time: %s
421<br /><br />
422Venue: %s
423</strong>
424<br /><br />
425Please bring this letter of invitation and the downloaded application form along with you on your screening date.
426<br /><br />
427You are expected to be available 30 minutes before the commencement of your Screening.
428</font>
429
430""" % (
431       self.context.display_fullname,
432       session,
433       sdate,
434       stime,
435       self.context.screening_venue)
436        return
437
438    @property
439    def title(self):
440        return None
441
442    def update(self):
443        if not self.context.screening_date:
444            self.flash(_('Forbidden'), type="warning")
445            self.redirect(self.url(self.context))
446
447    def render(self):
448        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
449        students_utils = getUtility(IStudentsUtils)
450        return students_utils.renderPDF(self,'screening_data.pdf',
451            self.context, applicantview, note=self.note)
Note: See TracBrowser for help on using the repository browser.