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

Last change on this file since 15992 was 15991, checked in by Henrik Bettermann, 5 years ago

Add Recruitment application.

  • Property svn:keywords set to Id
File size: 29.1 KB
Line 
1## $Id: browser.py 15991 2020-02-06 09:23: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 zope.catalog.interfaces import ICatalog
25from hurry.workflow.interfaces import IWorkflowState
26from waeup.kofa.interfaces import (
27    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
28from zope.formlib.textwidgets import BytesDisplayWidget
29from waeup.kofa.utils.helpers import string_from_bytes, file_size
30from waeup.kofa.applicants.browser import (
31    ApplicantCheckStatusPage, ApplicantBaseDisplayFormPage,
32    AdditionalFile)
33from waeup.kofa.applicants.workflow import STARTED, PAID
34from waeup.kofa.applicants.viewlets import PDFActionButton
35from waeup.kofa.applicants.interfaces import IApplicantRegisterUpdate
36from waeup.kofa.browser.layout import UtilityView, action
37from waeup.kofa.students.interfaces import IStudentsUtils
38from waeup.kofa.interfaces import IPDF
39from waeup.kofa.browser.viewlets import ManageActionButton
40from waeup.aaue.interfaces import MessageFactory as _
41from kofacustom.nigeria.applicants.browser import (
42    NigeriaApplicantDisplayFormPage,
43    NigeriaApplicantManageFormPage,
44    NigeriaApplicantEditFormPage,
45    NigeriaPDFApplicationSlip,
46    NigeriaApplicantRegistrationPage,
47    NigeriaExportPDFPaymentSlipPage,
48    )
49from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
50from waeup.aaue.applicants.interfaces import (
51    ICustomUGApplicant,
52    ICustomUGApplicantEdit,
53    ITranscriptApplicant,
54    ICertificateRequest,
55    ICustomApplicant,
56    IVerificationRequest,
57    ISendByEmailRequest,
58    IFedexRequest,
59    IRecruitment,
60    )
61
62UG_OMIT_FIELDS = (
63      'hq_type', 'hq_fname', 'hq_matric_no',
64      'hq_degree', 'hq_school', 'hq_session', 'hq_disc',
65      'hq_type2', 'hq_fname2', 'hq_matric_no2',
66      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
67      'hq_type3', 'hq_fname3', 'hq_matric_no3',
68      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
69      'nysc_year',
70      'nysc_location',
71      'nysc_lga',
72      'employer',
73      'emp_position',
74      'emp_start',
75      'emp_end',
76      'emp_reason',
77      'employer2',
78      'emp2_position',
79      'emp2_start',
80      'emp2_end',
81      'emp2_reason',
82      'former_matric',
83      )
84UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
85    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
86UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
87      'alr_fname', 'alr_no', 'alr_date',
88      'alr_results', 'notice')
89UG_OMIT_MANAGE_FIELDS = (
90    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
91UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
92    'student_id',
93    'notice',
94    'jamb_age',
95    'jamb_subjects',
96    'jamb_score',
97    'jamb_reg_number',
98    'aggregate',
99    'master_sheet_number',
100    'screening_venue',
101    'screening_score',
102    'screening_date'
103    )
104
105UDE_OMIT_FIELDS = (
106      'nysc_year',
107      'nysc_location',
108      'nysc_lga',
109      'employer',
110      'emp_position',
111      'emp_start',
112      'emp_end',
113      'emp_reason',
114      'employer2',
115      'emp2_position',
116      'emp2_start',
117      'emp2_end',
118      'emp2_reason',
119      'former_matric',
120      )
121UDE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
122    'jamb_subjects_list', 'master_sheet_number') + UDE_OMIT_FIELDS
123UDE_OMIT_PDF_FIELDS = UDE_OMIT_DISPLAY_FIELDS + UDE_OMIT_FIELDS + (
124      #'alr_fname', 'alr_no', 'alr_date', 'alr_results',
125      'hq_type2', 'hq_fname2', 'hq_matric_no2',
126      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
127      'hq_type3', 'hq_fname3', 'hq_matric_no3',
128      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
129      'notice')
130UDE_OMIT_MANAGE_FIELDS = (
131    'special_application','jamb_subjects_list',) + UDE_OMIT_FIELDS
132UDE_OMIT_EDIT_FIELDS = UDE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
133    'student_id',
134    'notice',
135    'jamb_age',
136    'jamb_subjects',
137    'jamb_score',
138    'jamb_reg_number',
139    'aggregate',
140    'master_sheet_number',
141    'screening_venue',
142    'screening_score',
143    'screening_date'
144    )
145
146#UG_OMIT_PDF_FIELDS = tuple([
147#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])
148
149#UG_OMIT_PDF_FIELDS += (
150#      'reg_number','alr_fname', 'alr_no', 'alr_date',
151#      'alr_results', 'notice'
152#      )
153
154PG_OMIT_FIELDS = (
155    'fst_sit_fname',
156    'fst_sit_no',
157    'fst_sit_date',
158    'fst_sit_type',
159    'fst_sit_results',
160    'scd_sit_fname',
161    'scd_sit_no',
162    'scd_sit_date',
163    'scd_sit_type',
164    'scd_sit_results',
165    #'programme_type',
166    'jamb_age',
167    'jamb_subjects',
168    'jamb_score',
169    'jamb_reg_number',
170    'aggregate'
171    )
172PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
173    'jamb_subjects_list',) + PG_OMIT_FIELDS
174PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + PG_OMIT_FIELDS + (
175      'reg_number','alr_fname', 'alr_no', 'alr_date',
176      'alr_results', 'notice',
177      'nysc_year',
178      'nysc_location',
179      'nysc_lga',
180      'former_matric',
181      )
182PG_OMIT_MANAGE_FIELDS = (
183    'special_application','jamb_subjects_list',) + PG_OMIT_FIELDS
184PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
185    'student_id',
186    'notice',
187    )
188
189PTEE_OMIT_FIELDS = (
190    'jamb_age',
191    'jamb_subjects',
192    'jamb_score',
193    'jamb_reg_number',
194    'aggregate'
195    )
196PTEE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
197    'jamb_subjects_list',) + PTEE_OMIT_FIELDS
198PTEE_OMIT_PDF_FIELDS = PTEE_OMIT_DISPLAY_FIELDS + PTEE_OMIT_FIELDS + (
199      'reg_number','alr_fname', 'alr_no', 'alr_date',
200      'alr_results', 'notice',
201      'nysc_year',
202      'nysc_location',
203      'nysc_lga',
204      'employer',
205      'emp_position',
206      'emp_start',
207      'emp_end',
208      'emp_reason',
209      'employer2',
210      'emp2_position',
211      'emp2_start',
212      'emp2_end',
213      'emp2_reason',
214      'former_matric',
215    )
216PTEE_OMIT_MANAGE_FIELDS = (
217    'special_application','jamb_subjects_list',) + PTEE_OMIT_FIELDS
218PTEE_OMIT_EDIT_FIELDS = PTEE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
219    'student_id',
220    'notice',
221    )
222
223UPDATE_OMIT_FIELDS = (
224    'firstname',
225    'middlename',
226    'lastname',
227    'sex',
228    'lga',
229    'course1',
230    )
231
232MAX_FILE_UPLOAD_SIZE = 1024 * 500
233
234class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
235    """A display view for applicant data.
236    """
237
238    @property
239    def form_fields(self):
240        if self.target is not None and self.target == 'trans':
241            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
242                'locked', 'suspended')
243            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
244            form_fields['perm_address'].custom_widget = BytesDisplayWidget
245            return form_fields
246        if self.target is not None and self.target == 'ver':
247            form_fields = grok.AutoFields(IVerificationRequest).omit(
248                'locked', 'suspended')
249            form_fields['body_address'].custom_widget = BytesDisplayWidget
250            return form_fields
251        if self.target is not None and self.target == 'fedex':
252            form_fields = grok.AutoFields(IFedexRequest).omit(
253                'locked', 'suspended')
254        if self.target is not None and self.target == 'rec':
255            form_fields = grok.AutoFields(IRecruitment).omit(
256                'locked', 'suspended')
257            form_fields['address'].custom_widget = BytesDisplayWidget
258            return form_fields
259        if self.target is not None and self.target == 'send':
260            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
261                'locked', 'suspended')
262            form_fields['body_address'].custom_widget = BytesDisplayWidget
263            return form_fields
264        if self.target is not None and self.target == 'cert':
265            form_fields = grok.AutoFields(ICertificateRequest).omit(
266                'locked', 'suspended')
267            #form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
268            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
269            return form_fields
270        # AAUE is using the same interface for all regular applications.
271        form_fields = grok.AutoFields(ICustomUGApplicant)
272        if self.target is not None and self.target.startswith('pg'):
273            for field in PG_OMIT_DISPLAY_FIELDS:
274                form_fields = form_fields.omit(field)
275        elif self.target is not None and self.target in ('ptee','dsh',):
276            for field in PTEE_OMIT_DISPLAY_FIELDS:
277                form_fields = form_fields.omit(field)
278        elif self.target is not None and self.target in ('bridge', 'ude',):
279            for field in UDE_OMIT_DISPLAY_FIELDS:
280                form_fields = form_fields.omit(field)
281        else:
282            for field in UG_OMIT_DISPLAY_FIELDS:
283                form_fields = form_fields.omit(field)
284        form_fields['perm_address'].custom_widget = BytesDisplayWidget
285        form_fields['notice'].custom_widget = BytesDisplayWidget
286        if not getattr(self.context, 'student_id'):
287            form_fields = form_fields.omit('student_id')
288        if not getattr(self.context, 'screening_score'):
289            form_fields = form_fields.omit('screening_score')
290        if not getattr(self.context, 'screening_venue') or \
291            self.context.state not in ('submitted', 'admitted', 'created'):
292            form_fields = form_fields.omit('screening_venue')
293        if not getattr(self.context, 'screening_date') or \
294            self.context.state not in ('submitted', 'admitted', 'created'):
295            form_fields = form_fields.omit('screening_date')
296        return form_fields
297
298    def getCourseAdmitted(self):
299        """Return link, title and code in html format to the certificate
300           admitted.
301        """
302        if self.layout.isApplicant():
303            return ''
304        course_admitted = self.context.course_admitted
305        if getattr(course_admitted, '__parent__',None):
306            url = self.url(course_admitted)
307            title = course_admitted.title
308            code = course_admitted.code
309            return '<a href="%s">%s - %s</a>' %(url,code,title)
310        return ''
311
312class CustomPDFActionButton(PDFActionButton):
313
314    @property
315    def target_url(self):
316        if self.context.state in ('initialized', 'started', 'paid'):
317            # or self.context.special or self.view.target in ('trans', 'cert'):
318            return
319        return self.view.url(self.view.context, self.target)
320
321
322class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
323
324    column_two_fields = ('applicant_id', 'reg_number',
325        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
326    #two_columns_design_fields = [
327    #    'fst_sit_fname', 'fst_sit_no', 'fst_sit_date',
328    #    'fst_sit_type', 'fst_sit_results',
329    #    'scd_sit_fname', 'scd_sit_no', 'scd_sit_date',
330    #    'scd_sit_type', 'scd_sit_results']
331
332    def _getCourseAdmittedLink(self, view):
333        return None
334
335    def _getDeptAndFaculty(self):
336        return [None, None]
337
338    @property
339    def note(self):
340        note = getattr(self.context.__parent__, 'application_slip_notice', None)
341        if note:
342            return '<br /><br />' + note
343        if self.target is not None and self.target in (
344            'trans', 'cert', 'ver', 'send'):
345            return
346        if self.context.sex == 'm':
347            pronoun = 'he'
348        else:
349            pronoun = 'she'
350        return '''
351The applicant has acknowledged that, if discovered at any time that %s does not possess
352any of the qualifications which %s claims %s has obtained, %s will be expelled from the
353University not be re-admitted for the same or any other programme, even if %s has
354upgraded previous qualifications or possess additional qualifications.
355
356''' % (
357    pronoun, pronoun, pronoun, pronoun, pronoun)
358
359    @property
360    def form_fields(self):
361        # AAUE is using the same interface for all regular applications.
362        form_fields = grok.AutoFields(ICustomUGApplicant)
363        if self.target is not None and self.target.startswith('pg'):
364            for field in PG_OMIT_PDF_FIELDS:
365                form_fields = form_fields.omit(field)
366        elif self.target is not None and self.target in ('ptee', 'dsh',):
367            for field in PTEE_OMIT_PDF_FIELDS:
368                form_fields = form_fields.omit(field)
369        elif self.target is not None and self.target in ('bridge', 'ude',):
370            for field in UDE_OMIT_PDF_FIELDS:
371                form_fields = form_fields.omit(field)
372        elif self.target is not None and self.target == 'trans':
373            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
374                'locked', 'suspended')
375        elif self.target is not None and self.target == 'ver':
376            form_fields = grok.AutoFields(IVerificationRequest).omit(
377                'locked', 'suspended')
378        elif self.target is not None and self.target == 'send':
379            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
380                'locked', 'suspended')
381        elif self.target is not None and self.target == 'cert':
382            form_fields = grok.AutoFields(ICertificateRequest).omit(
383                'locked', 'suspended')
384        else:
385            for field in UG_OMIT_PDF_FIELDS:
386                form_fields = form_fields.omit(field)
387        if not getattr(self.context, 'student_id'):
388            form_fields = form_fields.omit('student_id')
389        if not getattr(self.context, 'screening_score'):
390            form_fields = form_fields.omit('screening_score')
391        if not getattr(self.context, 'screening_venue'):
392            form_fields = form_fields.omit('screening_venue')
393        if not getattr(self.context, 'screening_date'):
394            form_fields = form_fields.omit('screening_date')
395        return form_fields
396
397class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
398    """A full edit view for applicant data.
399    """
400
401    def display_fileupload(self, filename):
402        if filename[1] == 'stateresult.pdf':
403            if self.target in ('trans', 'cert'):
404                return True
405        if filename[1] == 'verificationdoc.pdf':
406            if self.target in ('ver', 'send'):
407                return True
408        return False
409
410    @property
411    def form_fields(self):
412        if self.target is not None and self.target == 'trans':
413            form_fields = grok.AutoFields(ITranscriptApplicant)
414            form_fields['applicant_id'].for_display = True
415            return form_fields
416        if self.target is not None and self.target == 'cert':
417            form_fields = grok.AutoFields(ICertificateRequest)
418            form_fields['applicant_id'].for_display = True
419            return form_fields
420        if self.target is not None and self.target == 'ver':
421            form_fields = grok.AutoFields(IVerificationRequest)
422            form_fields['applicant_id'].for_display = True
423            return form_fields
424        if self.target is not None and self.target == 'send':
425            form_fields = grok.AutoFields(ISendByEmailRequest)
426            form_fields['applicant_id'].for_display = True
427            return form_fields
428        if self.target is not None and self.target == 'fedex':
429            form_fields = grok.AutoFields(IFedexRequest)
430            form_fields['applicant_id'].for_display = True
431            return form_fields
432        if self.target is not None and self.target == 'rec':
433            form_fields = grok.AutoFields(IRecruitment)
434            form_fields['applicant_id'].for_display = True
435            return form_fields
436        # AAUE is using the same interface for all regular applications.
437        form_fields = grok.AutoFields(ICustomUGApplicant)
438        if self.target is not None and self.target.startswith('pg'):
439            for field in PG_OMIT_MANAGE_FIELDS:
440                form_fields = form_fields.omit(field)
441        elif self.target is not None and self.target in ('ptee', 'dsh',):
442            for field in PTEE_OMIT_MANAGE_FIELDS:
443                form_fields = form_fields.omit(field)
444        elif self.target is not None and self.target in ('bridge', 'ude',):
445            for field in UDE_OMIT_MANAGE_FIELDS:
446                form_fields = form_fields.omit(field)
447        else:
448            for field in UG_OMIT_MANAGE_FIELDS:
449                form_fields = form_fields.omit(field)
450        form_fields['student_id'].for_display = True
451        form_fields['applicant_id'].for_display = True
452        return form_fields
453
454class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
455    """An applicant-centered edit view for applicant data.
456    """
457
458    def display_fileupload(self, filename):
459        if filename[1] == 'stateresult.pdf':
460            if self.target in ('trans', 'cert'):
461                return True
462        if filename[1] == 'verificationdoc.pdf':
463            if self.target in ('ver', 'send'):
464                return True
465        return False
466
467    def unremovable(self, ticket):
468        return True
469
470    def dataNotComplete(self, data):
471        store = getUtility(IExtFileStore)
472        # Temporarily enable passport upload also for cert and trans
473        # applications.
474        if self.context.__parent__.with_picture:
475            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
476                return _('No passport picture uploaded.')
477            if not self.target in ('cert', 'trans') and \
478                not self.request.form.get('confirm_passport', False):
479                return _('Passport picture confirmation box not ticked.')
480        if self.target in ('trans', 'cert') and \
481            not store.getFileByContext(self.context, attr=u'stateresult.pdf'):
482            return _('No statement of result pdf file uploaded.')
483        if self.target in ('ver',) and \
484            not store.getFileByContext(self.context, attr=u'verificationdoc.pdf'):
485            return _('No pdf file uploaded.')
486        if self.target == 'fedex':
487            cat = getUtility(ICatalog, name='applicants_catalog')
488            results = list(cat.searchResults(
489                applicant_id=(data['trans_id'], data['trans_id'])))
490            if not results:
491                return _('The transcript application id does not exist.')
492        return False
493
494    # AAUE applicants never see the 'Remove Selected Tickets' button.
495    @property
496    def display_actions(self):
497        # If the form is unlocked, applicants are allowed to save the form
498        # and remove unused tickets.
499        actions = [[_('Save')], []]
500        # Only in state started they can also add tickets.
501        if self.context.state == STARTED:
502            actions = [[_('Save')],
503                [_('Add online payment ticket')]]
504        # In state paid, they can submit the data and further add tickets
505        # if the application is special.
506        elif self.context.special and self.context.state == PAID:
507            actions = [[_('Save'), _('Finally Submit')],
508                [_('Add online payment ticket')]]
509        elif self.context.state == PAID:
510            actions = [[_('Save'), _('Finally Submit')], []]
511        return actions
512
513    @property
514    def form_fields(self):
515        if self.target is not None and self.target == 'trans':
516            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
517                'locked', 'suspended')
518            form_fields['applicant_id'].for_display = True
519            form_fields['reg_number'].for_display = True
520            form_fields['place_of_birth'].field.required = True
521            form_fields['date_of_birth'].field.required = True
522            form_fields['nationality'].field.required = True
523            form_fields['email'].field.required = True
524            form_fields['phone'].field.required = True
525            form_fields['perm_address'].field.required = True
526            form_fields['dispatch_address'].field.required = True
527            form_fields['entry_mode'].field.required = True
528            form_fields['entry_session'].field.required = True
529            form_fields['end_session'].field.required = True
530            form_fields['course_studied'].field.required = True
531            return form_fields
532        if self.target is not None and self.target == 'cert':
533            form_fields = grok.AutoFields(ICertificateRequest).omit(
534                'locked', 'suspended')
535            form_fields['applicant_id'].for_display = True
536            form_fields['reg_number'].for_display = True
537            form_fields['place_of_birth'].field.required = True
538            form_fields['date_of_birth'].field.required = True
539            form_fields['nationality'].field.required = True
540            form_fields['email'].field.required = True
541            form_fields['phone'].field.required = True
542            form_fields['entry_session'].field.required = True
543            form_fields['end_session'].field.required = True
544            form_fields['course_studied'].field.required = True
545            form_fields['certificate_type'].field.required = True
546            # Additional omissions
547            if self.context.__parent__.code == 'cert5':
548                for field in ('firstname', 'middlename', 'lastname'):
549                    form_fields[field].for_display = True
550            return form_fields
551        if self.target is not None and self.target == 'ver':
552            form_fields = grok.AutoFields(IVerificationRequest).omit(
553                'locked', 'suspended')
554            form_fields['applicant_id'].for_display = True
555            return form_fields
556        if self.target is not None and self.target == 'send':
557            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
558                'locked', 'suspended')
559            form_fields['applicant_id'].for_display = True
560            return form_fields
561        if self.target is not None and self.target == 'fedex':
562            form_fields = grok.AutoFields(IFedexRequest).omit(
563                'locked', 'suspended')
564            form_fields['applicant_id'].for_display = True
565            return form_fields
566        if self.target is not None and self.target == 'rec':
567            form_fields = grok.AutoFields(IRecruitment).omit(
568                'locked', 'suspended')
569            form_fields['applicant_id'].for_display = True
570            return form_fields
571        # AAUE is using the same interface for all regular applications.
572        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
573        if self.target is not None and self.target.startswith('pg'):
574            for field in PG_OMIT_EDIT_FIELDS:
575                form_fields = form_fields.omit(field)
576        elif self.target is not None and self.target in ('ptee','dsh',):
577            for field in PTEE_OMIT_EDIT_FIELDS:
578                form_fields = form_fields.omit(field)
579        elif self.target is not None and self.target in ('bridge', 'ude',):
580            for field in UDE_OMIT_EDIT_FIELDS:
581                form_fields = form_fields.omit(field)
582        else:
583            for field in UG_OMIT_EDIT_FIELDS:
584                form_fields = form_fields.omit(field)
585        # Additional omissions
586        if self.target is not None and self.target in ('ude', 'utme'):
587            for field in UPDATE_OMIT_FIELDS:
588                form_fields[field].for_display = True
589        form_fields['applicant_id'].for_display = True
590        form_fields['reg_number'].for_display = True
591        return form_fields
592
593    def update(self):
594        if self.context.locked or (
595            self.context.__parent__.expired and
596            self.context.__parent__.strict_deadline):
597            self.emit_lock_message()
598            return
599        if getattr(
600            self.context.course1, 'code', 'nocourse') == self.request.form.get(
601            'form.course2', None):
602            self.flash(_('2nd choice course must differ from 1st choice course.'),
603                       type='danger')
604            self.redirect(self.url(self.context))
605            return
606        if getattr(
607            self.context.course1, 'code', 'nocourse') == self.request.form.get(
608            'form.course3', None):
609            self.flash(_('3rd choice course must differ from 1st choice course.'),
610                       type='danger')
611            self.redirect(self.url(self.context))
612            return
613        super(CustomApplicantEditFormPage, self).update()
614        return
615
616class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
617    """Captcha'd registration page for applicants.
618    """
619
620    @property
621    def form_fields(self):
622        form_fields = None
623        if self.context.mode == 'update':
624            form_fields = grok.AutoFields(IApplicantRegisterUpdate).select(
625                'lastname','reg_number','email')
626            target = getattr(self.context, 'prefix', None)
627            if target in ('trans', 'cert'):
628                form_fields.get('reg_number').field.title = u'Matriculation Number'
629        else: #if self.context.mode == 'create':
630            form_fields = grok.AutoFields(ICustomUGApplicantEdit).select(
631                'firstname', 'middlename', 'lastname', 'email', 'phone')
632        return form_fields
633
634    def _redirect(self, email, password, applicant_id):
635        # Forward email and credentials to landing page.
636        self.redirect(self.url(self.context, 'registration_complete',
637            data = dict(email=email, password=password,
638            applicant_id=applicant_id)))
639        return
640
641    @property
642    def _postfix(self):
643        """Alumni records have to be imported into several containers.
644        Therefore a string must be added to their registration number
645        to make it unique.
646        """
647        if self.context.prefix in ('trans', 'cert'):
648            return self.context.code
649        return ''
650
651class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
652
653    @property
654    def payment_slip_download_warning(self):
655        return ''
656
657class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
658    """Captcha'd status checking page for applicants.
659    """
660    grok.template('applicantcheckstatus')
661
662class ScreeningInvitationActionButton(ManageActionButton):
663    grok.order(8) # This button should always be the last one.
664    grok.context(ICustomApplicant)
665    grok.view(CustomApplicantDisplayFormPage)
666    grok.require('waeup.viewApplication')
667    icon = 'actionicon_pdf.png'
668    text = _('Download screening invitation letter')
669    target = 'screening_invitation.pdf'
670
671    @property
672    def target_url(self):
673        if not self.context.screening_date or not self.context.state in (
674            'submitted', 'admitted', 'created'):
675            return ''
676        return self.view.url(self.view.context, self.target)
677
678class ExportScreeningInvitationLetter(UtilityView, grok.View):
679    """Deliver a slip with only screening data.
680    This form page is available only in AAUE.
681    """
682    grok.context(ICustomApplicant)
683    grok.name('screening_invitation.pdf')
684    grok.require('waeup.viewApplication')
685    prefix = 'form'
686
687    label = u'Screening Invitation Letter'
688
689    form_fields = []
690
691    @property
692    def note(self):
693        if self.context.screening_date:
694            year = self.context.__parent__.year
695            session = '%s/%s' % (year, year + 1)
696            sdate = self.context.screening_date
697            stime = ''
698            if '@' in self.context.screening_date:
699                sdate = self.context.screening_date.split('@')[0].strip()
700                stime = self.context.screening_date.split('@')[1].strip()
701            return """
702<br /><br /><br /><br /><font size='12'>
703Dear %s,
704<br /><br />
705You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
706<br /><br />
707<strong>Date: %s
708<br /><br />
709Time: %s
710<br /><br />
711Venue: %s
712</strong>
713<br /><br />
714Please bring this letter of invitation and the downloaded application form along with you on your screening date.
715<br /><br />
716You are expected to be available 30 minutes before the commencement of your Screening.
717</font>
718
719""" % (
720       self.context.display_fullname,
721       session,
722       sdate,
723       stime,
724       self.context.screening_venue)
725        return
726
727    @property
728    def title(self):
729        return None
730
731    def update(self):
732        if not self.context.screening_date or not self.context.state in (
733            'submitted', 'admitted', 'created'):
734            self.flash(_('Forbidden'), type="warning")
735            self.redirect(self.url(self.context))
736
737    def render(self):
738        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
739        students_utils = getUtility(IStudentsUtils)
740        return students_utils.renderPDF(self,'screening_data.pdf',
741            self.context, applicantview, note=self.note)
742
743class StateResult(AdditionalFile):
744    """Renders the pdf form extension for applicants.
745    """
746    grok.name('stateresult.pdf')
747
748class VerificationDoc(AdditionalFile):
749    """Renders the pdf form extension for applicants.
750    """
751    grok.name('verificationdoc.pdf')
Note: See TracBrowser for help on using the repository browser.