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

Last change on this file since 17669 was 17638, checked in by Henrik Bettermann, 12 months ago

… only ute

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