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

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

Notice field for display only.

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