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

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

Add trans_id field.

  • Property svn:keywords set to Id
File size: 28.8 KB
Line 
1## $Id: browser.py 15951 2020-01-24 12:58:03Z 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    @action(_('Save'), style='primary')
576    def save(self, **data):
577        if self.upload_success is False:  # False is not None!
578            # Error during image upload. Ignore other values.
579            return
580        if self.target == 'fedex':
581            cat = getUtility(ICatalog, name='applicants_catalog')
582            results = list(cat.searchResults(
583                applicant_id=(data['trans_id'], data['trans_id'])))
584            if not results:
585                self.flash(_('The transcript application id does not exist.'),
586                           type='danger')
587                return
588        self.applyData(self.context, **data)
589        self.flash(_('Form has been saved.'))
590        return
591
592    def update(self):
593        if self.context.locked or (
594            self.context.__parent__.expired and
595            self.context.__parent__.strict_deadline):
596            self.emit_lock_message()
597            return
598        if getattr(
599            self.context.course1, 'code', 'nocourse') == self.request.form.get(
600            'form.course2', None):
601            self.flash(_('2nd choice course must differ from 1st choice course.'),
602                       type='danger')
603            self.redirect(self.url(self.context))
604            return
605        if getattr(
606            self.context.course1, 'code', 'nocourse') == self.request.form.get(
607            'form.course3', None):
608            self.flash(_('3rd choice course must differ from 1st choice course.'),
609                       type='danger')
610            self.redirect(self.url(self.context))
611            return
612        super(CustomApplicantEditFormPage, self).update()
613        return
614
615class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
616    """Captcha'd registration page for applicants.
617    """
618
619    @property
620    def form_fields(self):
621        form_fields = None
622        if self.context.mode == 'update':
623            form_fields = grok.AutoFields(IApplicantRegisterUpdate).select(
624                'lastname','reg_number','email')
625            target = getattr(self.context, 'prefix', None)
626            if target in ('trans', 'cert'):
627                form_fields.get('reg_number').field.title = u'Matriculation Number'
628        else: #if self.context.mode == 'create':
629            form_fields = grok.AutoFields(ICustomUGApplicantEdit).select(
630                'firstname', 'middlename', 'lastname', 'email', 'phone')
631        return form_fields
632
633    def _redirect(self, email, password, applicant_id):
634        # Forward email and credentials to landing page.
635        self.redirect(self.url(self.context, 'registration_complete',
636            data = dict(email=email, password=password,
637            applicant_id=applicant_id)))
638        return
639
640    @property
641    def _postfix(self):
642        """Alumni records have to be imported into several containers.
643        Therefore a string must be added to their registration number
644        to make it unique.
645        """
646        if self.context.prefix in ('trans', 'cert'):
647            return self.context.code
648        return ''
649
650class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
651
652    @property
653    def payment_slip_download_warning(self):
654        return ''
655
656class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
657    """Captcha'd status checking page for applicants.
658    """
659    grok.template('applicantcheckstatus')
660
661class ScreeningInvitationActionButton(ManageActionButton):
662    grok.order(8) # This button should always be the last one.
663    grok.context(ICustomApplicant)
664    grok.view(CustomApplicantDisplayFormPage)
665    grok.require('waeup.viewApplication')
666    icon = 'actionicon_pdf.png'
667    text = _('Download screening invitation letter')
668    target = 'screening_invitation.pdf'
669
670    @property
671    def target_url(self):
672        if not self.context.screening_date or not self.context.state in (
673            'submitted', 'admitted', 'created'):
674            return ''
675        return self.view.url(self.view.context, self.target)
676
677class ExportScreeningInvitationLetter(UtilityView, grok.View):
678    """Deliver a slip with only screening data.
679    This form page is available only in AAUE.
680    """
681    grok.context(ICustomApplicant)
682    grok.name('screening_invitation.pdf')
683    grok.require('waeup.viewApplication')
684    prefix = 'form'
685
686    label = u'Screening Invitation Letter'
687
688    form_fields = []
689
690    @property
691    def note(self):
692        if self.context.screening_date:
693            year = self.context.__parent__.year
694            session = '%s/%s' % (year, year + 1)
695            sdate = self.context.screening_date
696            stime = ''
697            if '@' in self.context.screening_date:
698                sdate = self.context.screening_date.split('@')[0].strip()
699                stime = self.context.screening_date.split('@')[1].strip()
700            return """
701<br /><br /><br /><br /><font size='12'>
702Dear %s,
703<br /><br />
704You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
705<br /><br />
706<strong>Date: %s
707<br /><br />
708Time: %s
709<br /><br />
710Venue: %s
711</strong>
712<br /><br />
713Please bring this letter of invitation and the downloaded application form along with you on your screening date.
714<br /><br />
715You are expected to be available 30 minutes before the commencement of your Screening.
716</font>
717
718""" % (
719       self.context.display_fullname,
720       session,
721       sdate,
722       stime,
723       self.context.screening_venue)
724        return
725
726    @property
727    def title(self):
728        return None
729
730    def update(self):
731        if not self.context.screening_date or not self.context.state in (
732            'submitted', 'admitted', 'created'):
733            self.flash(_('Forbidden'), type="warning")
734            self.redirect(self.url(self.context))
735
736    def render(self):
737        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
738        students_utils = getUtility(IStudentsUtils)
739        return students_utils.renderPDF(self,'screening_data.pdf',
740            self.context, applicantview, note=self.note)
741
742class StateResult(AdditionalFile):
743    """Renders the pdf form extension for applicants.
744    """
745    grok.name('stateresult.pdf')
746
747class VerificationDoc(AdditionalFile):
748    """Renders the pdf form extension for applicants.
749    """
750    grok.name('verificationdoc.pdf')
Note: See TracBrowser for help on using the repository browser.