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

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

… only ute

  • Property svn:keywords set to Id
File size: 34.4 KB
Line 
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
22from zope.component import getUtility, getAdapter
23from zope.i18n import translate
24from zope.catalog.interfaces import ICatalog
25from hurry.workflow.interfaces import IWorkflowState
26from zope.component import queryUtility
27from zope.catalog.interfaces import ICatalog
28from waeup.kofa.interfaces import (
29    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
30from zope.formlib.textwidgets import BytesDisplayWidget
31from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
32from waeup.kofa.utils.helpers import string_from_bytes, file_size
33from waeup.kofa.applicants.browser import (
34    ApplicantCheckStatusPage,
35    AdditionalFile,
36    RefereeReportAddFormPage,
37    RefereeReportDisplayFormPage,
38    RefereeReportManageFormPage,
39    ExportPDFReportSlipPage,
40    ExportPDFReportSlipPage2)
41from waeup.kofa.applicants.workflow import STARTED, PAID
42from waeup.kofa.applicants.viewlets import PDFActionButton
43from waeup.kofa.applicants.interfaces import IApplicantRegisterUpdate
44from waeup.kofa.browser.layout import UtilityView, action
45from waeup.kofa.students.interfaces import IStudentsUtils
46from waeup.kofa.interfaces import IPDF
47from waeup.kofa.browser.viewlets import ManageActionButton
48from waeup.aaue.interfaces import MessageFactory as _
49from kofacustom.nigeria.applicants.browser import (
50    NigeriaApplicantDisplayFormPage,
51    NigeriaApplicantManageFormPage,
52    NigeriaApplicantEditFormPage,
53    NigeriaPDFApplicationSlip,
54    NigeriaApplicantRegistrationPage,
55    NigeriaExportPDFPaymentSlipPage,
56    )
57from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
58from waeup.aaue.applicants.interfaces import (
59    ICustomUGApplicant,
60    ICustomPGApplicant,
61    ICustomUGApplicantEdit,
62    ICustomPGApplicantEdit,
63    ITranscriptApplicant,
64    ICertificateRequest,
65    ICustomApplicant,
66    IVerificationRequest,
67    ISendByEmailRequest,
68    IFedexRequest,
69    IRecruitment,
70    ICustomApplicantOnlinePayment,
71    ICustomApplicantRefereeReport,
72    )
73
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',
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',
95      )
96UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
97    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
98UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
99      'alr_fname', 'alr_no', 'alr_date',
100      'alr_results', 'notice')
101UG_OMIT_MANAGE_FIELDS = (
102    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
103UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
104    'student_id',
105    'notice',
106    'jamb_age',
107    'jamb_subjects',
108    'jamb_score',
109    'jamb_reg_number',
110    'aggregate',
111    'master_sheet_number',
112    'screening_venue',
113    'screening_score',
114    'screening_date'
115    )
116
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 + (
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')
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
158#UG_OMIT_PDF_FIELDS = tuple([
159#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])
160
161#UG_OMIT_PDF_FIELDS += (
162#      'reg_number','alr_fname', 'alr_no', 'alr_date',
163#      'alr_results', 'notice'
164#      )
165
166PG_OMIT_FIELDS = (
167
168    )
169PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
170    ) + PG_OMIT_FIELDS
171PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + PG_OMIT_FIELDS + (
172      )
173PG_OMIT_MANAGE_FIELDS = (
174    ) + PG_OMIT_FIELDS
175PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
176    )
177
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
212UPDATE_OMIT_FIELDS = (
213    'firstname',
214    'middlename',
215    'lastname',
216    'sex',
217    'lga',
218    'course1',
219    )
220
221MAX_FILE_UPLOAD_SIZE = 1024 * 500
222
223class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
224    """A display view for applicant data.
225    """
226
227    @property
228    def form_fields(self):
229        if self.target is not None and self.target == 'trans':
230            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
231                'locked', 'suspended')
232            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
233            form_fields['perm_address'].custom_widget = BytesDisplayWidget
234            return form_fields
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
240        if self.target is not None and self.target == 'fedex':
241            form_fields = grok.AutoFields(IFedexRequest).omit(
242                'locked', 'suspended')
243            return form_fields
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
248            form_fields['position'].custom_widget = BytesDisplayWidget
249            return form_fields
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
255        if self.target is not None and self.target == 'cert':
256            form_fields = grok.AutoFields(ICertificateRequest).omit(
257                'locked', 'suspended')
258            return form_fields
259        if self.target is not None and self.target in ('ptee','dsh',):
260            form_fields = grok.AutoFields(ICustomUGApplicant)
261            for field in PTEE_OMIT_DISPLAY_FIELDS:
262                form_fields = form_fields.omit(field)
263        elif self.target is not None and self.target in ('bridge', 'ude',):
264            form_fields = grok.AutoFields(ICustomUGApplicant)
265            for field in UDE_OMIT_DISPLAY_FIELDS:
266                form_fields = form_fields.omit(field)
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)
271        else:
272            form_fields = grok.AutoFields(ICustomUGApplicant)
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')
279        if not getattr(self.context, 'screening_venue') or \
280            self.context.state not in ('submitted', 'admitted', 'created'):
281            form_fields = form_fields.omit('screening_venue')
282        if not getattr(self.context, 'screening_date') or \
283            self.context.state not in ('submitted', 'admitted', 'created'):
284            form_fields = form_fields.omit('screening_date')
285        return form_fields
286
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
301class CustomPDFActionButton(PDFActionButton):
302
303    @property
304    def target_url(self):
305        if self.context.state in ('initialized', 'started', 'paid'):
306            # or self.context.special or self.view.target in ('trans', 'cert'):
307            return
308        return self.view.url(self.view.context, self.target)
309
310
311class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
312
313    column_two_fields = ('applicant_id', 'reg_number',
314        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
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']
320
321    def _getCourseAdmittedLink(self, view):
322        return None
323
324    def _getDeptAndFaculty(self):
325        return [None, None]
326
327    @property
328    def note(self):
329        note = getattr(self.context.__parent__, 'application_slip_notice', None)
330        if note:
331            return '<br /><br />' + note
332        if self.target is not None and self.target in (
333            'trans', 'cert', 'ver', 'send', 'fedex'):
334            return
335        if self.context.sex == 'm':
336            pronoun = 'he'
337        else:
338            pronoun = 'she'
339        return '''
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
342University not be re-admitted for the same or any other programme, even if %s has
343upgraded previous qualifications or possess additional qualifications.
344
345''' % (
346    pronoun, pronoun, pronoun, pronoun, pronoun)
347
348    @property
349    def form_fields(self):
350        # AAUE is using the same interface for all regular applications.
351        form_fields = grok.AutoFields(ICustomUGApplicant)
352        if self.target is not None and self.target.startswith('pg'):
353            for field in PG_OMIT_PDF_FIELDS:
354                form_fields = grok.AutoFields(ICustomPGApplicant)
355                form_fields = form_fields.omit(field)
356        elif self.target is not None and self.target in ('ptee', 'dsh',):
357            for field in PTEE_OMIT_PDF_FIELDS:
358                form_fields = form_fields.omit(field)
359        elif self.target is not None and self.target in ('bridge', 'ude',):
360            for field in UDE_OMIT_PDF_FIELDS:
361                form_fields = form_fields.omit(field)
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')
374        elif self.target is not None and self.target == 'fedex':
375            form_fields = grok.AutoFields(IFedexRequest).omit(
376                'locked', 'suspended')
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')
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')
402        return form_fields
403
404class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
405    """A full edit view for applicant data.
406    """
407
408    def display_fileupload(self, filename):
409        if filename[1] == 'stateresult':
410            if self.target in ('trans', 'cert'):
411                return True
412        if filename[1] == 'verificationdoc':
413            if self.target in ('ver', 'send'):
414                return True
415        return False
416
417    @property
418    def form_fields(self):
419        if self.target is not None and self.target == 'trans':
420            form_fields = grok.AutoFields(ITranscriptApplicant)
421            form_fields['applicant_id'].for_display = True
422            return form_fields
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
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
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
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
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
443        # AAUE is using the same interface for all regular applications.
444        form_fields = grok.AutoFields(ICustomUGApplicant)
445        if self.target is not None and self.target.startswith('pg'):
446            form_fields = grok.AutoFields(ICustomPGApplicant)
447            for field in PG_OMIT_MANAGE_FIELDS:
448                form_fields = form_fields.omit(field)
449        elif self.target is not None and self.target in ('ptee', 'dsh',):
450            for field in PTEE_OMIT_MANAGE_FIELDS:
451                form_fields = form_fields.omit(field)
452        elif self.target is not None and self.target in ('bridge', 'ude',):
453            for field in UDE_OMIT_MANAGE_FIELDS:
454                form_fields = form_fields.omit(field)
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
466    def display_fileupload(self, filename):
467        if filename[1] == 'stateresult':
468            if self.target in ('trans', 'cert'):
469                return True
470        if filename[1] == 'verificationdoc':
471            if self.target in ('ver', 'send'):
472                return True
473        return False
474
475    def unremovable(self, ticket):
476        return True
477
478    def dataNotComplete(self, data):
479        store = getUtility(IExtFileStore)
480        # Temporarily enable passport upload also for cert and trans
481        # applications.
482        if self.context.__parent__.with_picture:
483            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
484                return _('No passport picture uploaded.')
485            if not self.target in ('cert', 'trans') and \
486                not self.request.form.get('confirm_passport', False):
487                return _('Passport picture confirmation box not ticked.')
488        if self.target in ('trans', 'cert') and \
489            not store.getFileByContext(self.context, attr=u'stateresult'):
490            return _('No statement of result pdf file uploaded.')
491        if self.target in ('ver',) and \
492            not store.getFileByContext(self.context, attr=u'verificationdoc'):
493            return _('No pdf file uploaded.')
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.')
500        return False
501
502    # AAUE applicants never see the 'Remove Selected Tickets' button.
503    @property
504    def display_actions(self):
505        # If the form is unlocked, applicants are allowed to save the form
506        # and remove unused tickets.
507        actions = [[_('Save')], []]
508        # Only in state started they can also add tickets.
509        if self.context.state == STARTED:
510            actions = [[_('Save')],
511                [_('Add online payment ticket')]]
512        # In state paid, they can submit the data and further add tickets
513        # if the application is special.
514        elif self.context.special and self.context.state == PAID:
515            actions = [[_('Save'), _('Finally Submit')],
516                [_('Add online payment ticket')]]
517        elif self.context.state == PAID:
518            actions = [[_('Save'), _('Finally Submit')], []]
519        return actions
520
521    @property
522    def form_fields(self):
523        if self.target is not None and self.target == 'trans':
524            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
525                'locked', 'suspended')
526            form_fields['applicant_id'].for_display = True
527            form_fields['reg_number'].for_display = True
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
539            return form_fields
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
544            form_fields['reg_number'].for_display = True
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
554            # Additional omissions
555            if self.context.__parent__.code == 'cert5':
556                for field in ('firstname', 'middlename', 'lastname'):
557                    form_fields[field].for_display = True
558            return form_fields
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
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
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
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
579        # AAUE is using the same interface for all regular applications.
580        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
581        if self.target is not None and self.target.startswith('pg'):
582            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
583            for field in PG_OMIT_EDIT_FIELDS:
584                form_fields = form_fields.omit(field)
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
589            form_fields['notice'].for_display = True
590        elif self.target is not None and self.target in ('ptee','dsh',):
591            for field in PTEE_OMIT_EDIT_FIELDS:
592                form_fields = form_fields.omit(field)
593        elif self.target is not None and self.target in ('bridge', 'ude',):
594            for field in UDE_OMIT_EDIT_FIELDS:
595                form_fields = form_fields.omit(field)
596        else:
597            for field in UG_OMIT_EDIT_FIELDS:
598                form_fields = form_fields.omit(field)
599        # Additional omissions
600        if self.target is not None and self.target in ('ude', 'utme'):
601            for field in UPDATE_OMIT_FIELDS:
602                form_fields[field].for_display = True
603        form_fields['applicant_id'].for_display = True
604        form_fields['reg_number'].for_display = True
605        return form_fields
606
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
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')
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
644        if getattr(self.context.course1, 'code', 'nocourse') == course2_in_form:
645            self.flash(_('2nd choice course must differ from 1st choice course.'),
646                       type='danger')
647            self.redirect(self.url(self.context))
648            return
649        if getattr(self.context.course1, 'code', 'nocourse') == course3_in_form:
650            self.flash(_('3rd choice course must differ from 1st choice course.'),
651                       type='danger')
652            self.redirect(self.url(self.context))
653            return
654        super(CustomApplicantEditFormPage, self).update()
655        return
656
657class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
658    """Captcha'd registration page for applicants.
659    """
660
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')
667            target = getattr(self.context, 'prefix', None)
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
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)))
680        return
681
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
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
709class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
710
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
717    @property
718    def payment_slip_download_warning(self):
719        return ''
720
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
732class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
733    """Captcha'd status checking page for applicants.
734    """
735    grok.template('applicantcheckstatus')
736
737class ScreeningInvitationActionButton(ManageActionButton):
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'
745
746    @property
747    def target_url(self):
748        if not self.context.screening_date or not self.context.state in (
749            'submitted', 'admitted', 'created'):
750            return ''
751        return self.view.url(self.view.context, self.target)
752
753class ExportScreeningInvitationLetter(UtilityView, grok.View):
754    """Deliver a slip with only screening data.
755    This form page is available only in AAUE.
756    """
757    grok.context(ICustomApplicant)
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:
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()
776            return """
777<br /><br /><br /><br /><font size='12'>
778Dear %s,
779<br /><br />
780You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
781<br /><br />
782<strong>Date: %s
783<br /><br />
784Time: %s
785<br /><br />
786Venue: %s
787</strong>
788<br /><br />
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.
792</font>
793
794""" % (
795       self.context.display_fullname,
796       session,
797       sdate,
798       stime,
799       self.context.screening_venue)
800        return
801
802    @property
803    def title(self):
804        return None
805
806    def update(self):
807        if not self.context.screening_date or not self.context.state in (
808            'submitted', 'admitted', 'created'):
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',
816            self.context, applicantview, note=self.note)
817
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
832class CustomRefereeReportManageFormPage(RefereeReportManageFormPage):
833    """A displaymanage for referee reports.
834    """
835    form_fields = grok.AutoFields(ICustomApplicantRefereeReport).omit('creation_date')
836
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
847class StateResult(AdditionalFile):
848    """Renders the pdf form extension for applicants.
849    """
850    grok.name('stateresult')
851
852class VerificationDoc(AdditionalFile):
853    """Renders the pdf form extension for applicants.
854    """
855    grok.name('verificationdoc')
Note: See TracBrowser for help on using the repository browser.