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

Last change on this file since 17388 was 16871, checked in by Henrik Bettermann, 3 years ago

Add fields and customize manage form.

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