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

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

Adjust to base package.

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