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
RevLine 
[10298]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
[13996]22from zope.component import getUtility, getAdapter
23from zope.i18n import translate
[14027]24from hurry.workflow.interfaces import IWorkflowState
[10298]25from waeup.kofa.interfaces import (
[13996]26    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
[10298]27from zope.formlib.textwidgets import BytesDisplayWidget
28from waeup.kofa.utils.helpers import string_from_bytes, file_size
[13996]29from waeup.kofa.applicants.browser import (
[15948]30    ApplicantCheckStatusPage, ApplicantBaseDisplayFormPage,
31    AdditionalFile)
[14027]32from waeup.kofa.applicants.workflow import STARTED, PAID
[13538]33from waeup.kofa.applicants.viewlets import PDFActionButton
[14460]34from waeup.kofa.applicants.interfaces import IApplicantRegisterUpdate
[13996]35from waeup.kofa.browser.layout import UtilityView
36from waeup.kofa.students.interfaces import IStudentsUtils
37from waeup.kofa.interfaces import IPDF
[13997]38from waeup.kofa.browser.viewlets import ManageActionButton
[10298]39from waeup.aaue.interfaces import MessageFactory as _
40from kofacustom.nigeria.applicants.browser import (
41    NigeriaApplicantDisplayFormPage,
42    NigeriaApplicantManageFormPage,
43    NigeriaApplicantEditFormPage,
44    NigeriaPDFApplicationSlip,
[10929]45    NigeriaApplicantRegistrationPage,
[11755]46    NigeriaExportPDFPaymentSlipPage,
[13545]47    )
48from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
[10298]49from waeup.aaue.applicants.interfaces import (
50    ICustomUGApplicant,
[13544]51    ICustomUGApplicantEdit,
[13996]52    ITranscriptApplicant,
[14304]53    ICertificateRequest,
[15530]54    ICustomApplicant,
[15531]55    IVerificationRequest,
56    ISendByEmailRequest
[11291]57    )
[10298]58
[13545]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',
[13679]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',
[13545]80      )
[13546]81UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
[13977]82    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
[13545]83UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
[14363]84      'alr_fname', 'alr_no', 'alr_date',
[13545]85      'alr_results', 'notice')
[13546]86UG_OMIT_MANAGE_FIELDS = (
87    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
88UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
[13545]89    'student_id',
90    'notice',
91    'jamb_age',
92    'jamb_subjects',
93    'jamb_score',
94    'jamb_reg_number',
[13679]95    'aggregate',
[13977]96    'master_sheet_number',
[13996]97    'screening_venue',
98    'screening_score',
99    'screening_date'
[13679]100    )
[10298]101
[14209]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 + (
[15091]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')
[14209]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
[13545]143#UG_OMIT_PDF_FIELDS = tuple([
144#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])
[11291]145
[13545]146#UG_OMIT_PDF_FIELDS += (
147#      'reg_number','alr_fname', 'alr_no', 'alr_date',
148#      'alr_results', 'notice'
149#      )
[13538]150
[13545]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',
[13977]162    #'programme_type',
[13546]163    'jamb_age',
164    'jamb_subjects',
165    'jamb_score',
166    'jamb_reg_number',
167    'aggregate'
[13545]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',
[13679]173      'alr_results', 'notice',
174      'nysc_year',
175      'nysc_location',
176      'nysc_lga',
177      'former_matric',
178      )
[13545]179PG_OMIT_MANAGE_FIELDS = (
180    'special_application','jamb_subjects_list',) + PG_OMIT_FIELDS
[13546]181PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
[13545]182    'student_id',
183    'notice',
[13546]184    )
[13545]185
[13679]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
[14150]220UPDATE_OMIT_FIELDS = (
221    'firstname',
222    'middlename',
223    'lastname',
224    'sex',
225    'lga',
226    'course1',
227    )
228
[15113]229MAX_FILE_UPLOAD_SIZE = 1024 * 500
230
[10298]231class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
232    """A display view for applicant data.
233    """
234
235    @property
236    def form_fields(self):
[13538]237        if self.target is not None and self.target == 'trans':
[13544]238            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
[14580]239                'locked', 'suspended')
[13544]240            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
241            form_fields['perm_address'].custom_widget = BytesDisplayWidget
242            return form_fields
[15530]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
[15531]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
[14304]253        if self.target is not None and self.target == 'cert':
254            form_fields = grok.AutoFields(ICertificateRequest).omit(
[14580]255                'locked', 'suspended')
[15099]256            #form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
257            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
[14304]258            return form_fields
[13538]259        # AAUE is using the same interface for all regular applications.
[11291]260        form_fields = grok.AutoFields(ICustomUGApplicant)
[13538]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)
[15521]264        elif self.target is not None and self.target in ('ptee','dsh',):
[13679]265            for field in PTEE_OMIT_DISPLAY_FIELDS:
[10298]266                form_fields = form_fields.omit(field)
[15217]267        elif self.target is not None and self.target in ('bridge', 'ude',):
[14209]268            for field in UDE_OMIT_DISPLAY_FIELDS:
269                form_fields = form_fields.omit(field)
[10298]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')
[14840]279        if not getattr(self.context, 'screening_venue') or \
280            self.context.state not in ('submitted', 'admitted', 'created'):
[10298]281            form_fields = form_fields.omit('screening_venue')
[14840]282        if not getattr(self.context, 'screening_date') or \
283            self.context.state not in ('submitted', 'admitted', 'created'):
[10298]284            form_fields = form_fields.omit('screening_date')
285        return form_fields
286
[14371]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
[13538]301class CustomPDFActionButton(PDFActionButton):
302
303    @property
304    def target_url(self):
[15835]305        if self.context.state in ('initialized', 'started', 'paid'):
306            # or self.context.special or self.view.target in ('trans', 'cert'):
[13540]307            return
308        return self.view.url(self.view.context, self.target)
[13538]309
310
[10298]311class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
312
[10311]313    column_two_fields = ('applicant_id', 'reg_number',
314        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
[13679]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']
[10311]320
[14228]321    def _getCourseAdmittedLink(self, view):
322        return None
323
324    def _getDeptAndFaculty(self):
325        return [None, None]
326
[10301]327    @property
328    def note(self):
[14057]329        note = getattr(self.context.__parent__, 'application_slip_notice', None)
330        if note:
331            return '<br /><br />' + note
[15835]332        if self.target is not None and self.target in (
333            'trans', 'cert', 'ver', 'send'):
334            return
[10301]335        if self.context.sex == 'm':
336            pronoun = 'he'
337        else:
338            pronoun = 'she'
339        return '''
[10897]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
[14224]342University not be re-admitted for the same or any other programme, even if %s has
343upgraded previous qualifications or possess additional qualifications.
344
[10331]345''' % (
[10301]346    pronoun, pronoun, pronoun, pronoun, pronoun)
[10298]347
348    @property
349    def form_fields(self):
[13538]350        # AAUE is using the same interface for all regular applications.
[11291]351        form_fields = grok.AutoFields(ICustomUGApplicant)
[13538]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)
[15521]355        elif self.target is not None and self.target in ('ptee', 'dsh',):
[13679]356            for field in PTEE_OMIT_PDF_FIELDS:
[10298]357                form_fields = form_fields.omit(field)
[15217]358        elif self.target is not None and self.target in ('bridge', 'ude',):
[14209]359            for field in UDE_OMIT_PDF_FIELDS:
360                form_fields = form_fields.omit(field)
[15835]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')
[10298]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
[15948]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
[10298]399    @property
400    def form_fields(self):
[13538]401        if self.target is not None and self.target == 'trans':
[13544]402            form_fields = grok.AutoFields(ITranscriptApplicant)
[13538]403            form_fields['applicant_id'].for_display = True
404            return form_fields
[14304]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
[15530]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
[15531]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
[13538]417        # AAUE is using the same interface for all regular applications.
[11291]418        form_fields = grok.AutoFields(ICustomUGApplicant)
[13538]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)
[15521]422        elif self.target is not None and self.target in ('ptee', 'dsh',):
[13679]423            for field in PTEE_OMIT_MANAGE_FIELDS:
[10298]424                form_fields = form_fields.omit(field)
[15217]425        elif self.target is not None and self.target in ('bridge', 'ude',):
[14209]426            for field in UDE_OMIT_MANAGE_FIELDS:
427                form_fields = form_fields.omit(field)
[10298]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
[15948]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
[14027]448    def unremovable(self, ticket):
449        return True
450
[15639]451    def dataNotComplete(self, data):
[15099]452        store = getUtility(IExtFileStore)
[15265]453        # Temporarily enable passport upload also for cert and trans
454        # applications.
[15503]455        if self.context.__parent__.with_picture:
[15100]456            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
[15099]457                return _('No passport picture uploaded.')
[15265]458            if not self.target[:4] in ('cert', 'tran') and \
459                not self.request.form.get('confirm_passport', False):
[15099]460                return _('Passport picture confirmation box not ticked.')
[15132]461        if self.target in ('trans', 'cert') and \
[15113]462            not store.getFileByContext(self.context, attr=u'stateresult.pdf'):
463            return _('No statement of result pdf file uploaded.')
[15531]464        if self.target in ('ver',) and \
465            not store.getFileByContext(self.context, attr=u'verificationdoc.pdf'):
466            return _('No pdf file uploaded.')
[15113]467
[15099]468        return False
469
[14027]470    # AAUE applicants never see the 'Remove Selected Tickets' button.
[10298]471    @property
[14027]472    def display_actions(self):
473        # If the form is unlocked, applicants are allowed to save the form
[14029]474        # and remove unused tickets.
475        actions = [[_('Save')], []]
[14027]476        # Only in state started they can also add tickets.
[14822]477        if self.context.state == STARTED:
[14029]478            actions = [[_('Save')],
479                [_('Add online payment ticket')]]
[14027]480        # In state paid, they can submit the data and further add tickets
481        # if the application is special.
[14822]482        elif self.context.special and self.context.state == PAID:
[14027]483            actions = [[_('Save'), _('Finally Submit')],
[14029]484                [_('Add online payment ticket')]]
[14822]485        elif self.context.state == PAID:
[14029]486            actions = [[_('Save'), _('Finally Submit')], []]
[14027]487        return actions
488
489    @property
[10298]490    def form_fields(self):
[13538]491        if self.target is not None and self.target == 'trans':
[13544]492            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
493                'locked', 'suspended')
[13538]494            form_fields['applicant_id'].for_display = True
[14472]495            form_fields['reg_number'].for_display = True
[15276]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
[13538]507            return form_fields
[14304]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
[14472]512            form_fields['reg_number'].for_display = True
[15276]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
[14696]522            # Additional omissions
523            if self.context.__parent__.code == 'cert5':
524                for field in ('firstname', 'middlename', 'lastname'):
525                    form_fields[field].for_display = True
[14304]526            return form_fields
[15530]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
[15531]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
[13538]537        # AAUE is using the same interface for all regular applications.
[11291]538        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
[13538]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)
[15521]542        elif self.target is not None and self.target in ('ptee','dsh',):
[13679]543            for field in PTEE_OMIT_EDIT_FIELDS:
[10298]544                form_fields = form_fields.omit(field)
[15217]545        elif self.target is not None and self.target in ('bridge', 'ude',):
[14209]546            for field in UDE_OMIT_EDIT_FIELDS:
547                form_fields = form_fields.omit(field)
[10298]548        else:
549            for field in UG_OMIT_EDIT_FIELDS:
550                form_fields = form_fields.omit(field)
[14150]551        # Additional omissions
[14696]552        if self.target is not None and self.target in ('ude', 'utme'):
[14150]553            for field in UPDATE_OMIT_FIELDS:
554                form_fields[field].for_display = True
[10298]555        form_fields['applicant_id'].for_display = True
556        form_fields['reg_number'].for_display = True
557        return form_fields
[10929]558
[15113]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
[15459]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
[15113]579        super(CustomApplicantEditFormPage, self).update()
580        return
581
[10929]582class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
583    """Captcha'd registration page for applicants.
584    """
585
[14460]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')
[14465]592            target = getattr(self.context, 'prefix', None)
[14460]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
[10929]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)))
[11755]605        return
606
[14579]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
[11755]617class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
618
619    @property
620    def payment_slip_download_warning(self):
[13422]621        return ''
622
623class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
624    """Captcha'd status checking page for applicants.
625    """
626    grok.template('applicantcheckstatus')
[13996]627
[14822]628class ScreeningInvitationActionButton(ManageActionButton):
[13997]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'
[13996]636
[13997]637    @property
638    def target_url(self):
[14822]639        if not self.context.screening_date or not self.context.state in (
[14824]640            'submitted', 'admitted', 'created'):
[13997]641            return ''
642        return self.view.url(self.view.context, self.target)
643
[13996]644class ExportScreeningInvitationLetter(UtilityView, grok.View):
645    """Deliver a slip with only screening data.
646    This form page is available only in AAUE.
647    """
[13997]648    grok.context(ICustomApplicant)
[13996]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:
[13999]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()
[13996]667            return """
668<br /><br /><br /><br /><font size='12'>
669Dear %s,
670<br /><br />
[13999]671You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
[13996]672<br /><br />
[13999]673<strong>Date: %s
[13996]674<br /><br />
[13999]675Time: %s
676<br /><br />
[13997]677Venue: %s
678</strong>
[13996]679<br /><br />
[14015]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.
[13996]683</font>
684
[13999]685""" % (
686       self.context.display_fullname,
687       session,
688       sdate,
689       stime,
[13996]690       self.context.screening_venue)
691        return
692
693    @property
694    def title(self):
695        return None
696
697    def update(self):
[14822]698        if not self.context.screening_date or not self.context.state in (
[14824]699            'submitted', 'admitted', 'created'):
[13996]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',
[14015]707            self.context, applicantview, note=self.note)
[15113]708
[15948]709class StateResult(AdditionalFile):
[15113]710    """Renders the pdf form extension for applicants.
711    """
712    grok.name('stateresult.pdf')
713
[15948]714class VerificationDoc(AdditionalFile):
[15530]715    """Renders the pdf form extension for applicants.
716    """
717    grok.name('verificationdoc.pdf')
Note: See TracBrowser for help on using the repository browser.