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

Last change on this file since 15275 was 15265, checked in by Henrik Bettermann, 6 years ago

Enable passport upload also for cert and trans applications.

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