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

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

Check transcript application id before submission.

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