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

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

Finetune fedex payment application.

Change bank account.

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