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

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

Configure split payment. Remove save method. Doesn't wirk.

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