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

Last change on this file since 14015 was 14015, checked in by uli, 8 years ago

Change invitation letter text as requested in #234.

  • Property svn:keywords set to Id
File size: 14.8 KB
Line 
1## $Id: browser.py 14015 2016-07-05 18:23:06Z uli $
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 waeup.kofa.interfaces import (
25    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
26from zope.formlib.textwidgets import BytesDisplayWidget
27from waeup.kofa.utils.helpers import string_from_bytes, file_size
28from waeup.kofa.applicants.browser import (
29    ApplicantCheckStatusPage, ApplicantBaseDisplayFormPage)
30from waeup.kofa.applicants.viewlets import PDFActionButton
31from waeup.kofa.browser.layout import UtilityView
32from waeup.kofa.students.interfaces import IStudentsUtils
33from waeup.kofa.interfaces import IPDF
34from waeup.kofa.applicants.interfaces import IApplicant
35from waeup.kofa.browser.viewlets import ManageActionButton
36from waeup.aaue.interfaces import MessageFactory as _
37from kofacustom.nigeria.applicants.browser import (
38    NigeriaApplicantDisplayFormPage,
39    NigeriaApplicantManageFormPage,
40    NigeriaApplicantEditFormPage,
41    NigeriaPDFApplicationSlip,
42    NigeriaApplicantRegistrationPage,
43    NigeriaExportPDFPaymentSlipPage,
44    )
45from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
46from waeup.aaue.applicants.interfaces import (
47    ICustomUGApplicant,
48    ICustomUGApplicantEdit,
49    ITranscriptApplicant,
50    ICustomApplicant
51    )
52
53UG_OMIT_FIELDS = (
54      'hq_type', 'hq_fname', 'hq_matric_no',
55      'hq_degree', 'hq_school', 'hq_session', 'hq_disc',
56      'hq_type2', 'hq_fname2', 'hq_matric_no2',
57      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
58      'hq_type3', 'hq_fname3', 'hq_matric_no3',
59      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
60      'nysc_year',
61      'nysc_location',
62      'nysc_lga',
63      'employer',
64      'emp_position',
65      'emp_start',
66      'emp_end',
67      'emp_reason',
68      'employer2',
69      'emp2_position',
70      'emp2_start',
71      'emp2_end',
72      'emp2_reason',
73      'former_matric',
74      )
75UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
76    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
77UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
78      'reg_number','alr_fname', 'alr_no', 'alr_date',
79      'alr_results', 'notice')
80UG_OMIT_MANAGE_FIELDS = (
81    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
82UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
83    'student_id',
84    'notice',
85    'jamb_age',
86    'jamb_subjects',
87    'jamb_score',
88    'jamb_reg_number',
89    'aggregate',
90
91    'firstname',
92    'middlename',
93    'lastname',
94    'sex',
95    'lga',
96    'course1',
97    'master_sheet_number',
98    'screening_venue',
99    'screening_score',
100    'screening_date'
101    )
102
103#UG_OMIT_PDF_FIELDS = tuple([
104#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])
105
106#UG_OMIT_PDF_FIELDS += (
107#      'reg_number','alr_fname', 'alr_no', 'alr_date',
108#      'alr_results', 'notice'
109#      )
110
111PG_OMIT_FIELDS = (
112    'fst_sit_fname',
113    'fst_sit_no',
114    'fst_sit_date',
115    'fst_sit_type',
116    'fst_sit_results',
117    'scd_sit_fname',
118    'scd_sit_no',
119    'scd_sit_date',
120    'scd_sit_type',
121    'scd_sit_results',
122    #'programme_type',
123    'jamb_age',
124    'jamb_subjects',
125    'jamb_score',
126    'jamb_reg_number',
127    'aggregate'
128    )
129PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
130    'jamb_subjects_list',) + PG_OMIT_FIELDS
131PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + PG_OMIT_FIELDS + (
132      'reg_number','alr_fname', 'alr_no', 'alr_date',
133      'alr_results', 'notice',
134      'nysc_year',
135      'nysc_location',
136      'nysc_lga',
137      'former_matric',
138      )
139PG_OMIT_MANAGE_FIELDS = (
140    'special_application','jamb_subjects_list',) + PG_OMIT_FIELDS
141PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
142    'student_id',
143    'notice',
144    )
145
146PTEE_OMIT_FIELDS = (
147    'jamb_age',
148    'jamb_subjects',
149    'jamb_score',
150    'jamb_reg_number',
151    'aggregate'
152    )
153PTEE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
154    'jamb_subjects_list',) + PTEE_OMIT_FIELDS
155PTEE_OMIT_PDF_FIELDS = PTEE_OMIT_DISPLAY_FIELDS + PTEE_OMIT_FIELDS + (
156      'reg_number','alr_fname', 'alr_no', 'alr_date',
157      'alr_results', 'notice',
158      'nysc_year',
159      'nysc_location',
160      'nysc_lga',
161      'employer',
162      'emp_position',
163      'emp_start',
164      'emp_end',
165      'emp_reason',
166      'employer2',
167      'emp2_position',
168      'emp2_start',
169      'emp2_end',
170      'emp2_reason',
171      'former_matric',
172    )
173PTEE_OMIT_MANAGE_FIELDS = (
174    'special_application','jamb_subjects_list',) + PTEE_OMIT_FIELDS
175PTEE_OMIT_EDIT_FIELDS = PTEE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
176    'student_id',
177    'notice',
178    )
179
180class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
181    """A display view for applicant data.
182    """
183
184    @property
185    def form_fields(self):
186        if self.target is not None and self.target == 'trans':
187            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
188                'locked', 'suspended')
189            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
190            form_fields['perm_address'].custom_widget = BytesDisplayWidget
191            return form_fields
192        # AAUE is using the same interface for all regular applications.
193        form_fields = grok.AutoFields(ICustomUGApplicant)
194        if self.target is not None and self.target.startswith('pg'):
195            for field in PG_OMIT_DISPLAY_FIELDS:
196                form_fields = form_fields.omit(field)
197        elif self.target is not None and self.target in ('ptee', 'ude'):
198            for field in PTEE_OMIT_DISPLAY_FIELDS:
199                form_fields = form_fields.omit(field)
200        else:
201            for field in UG_OMIT_DISPLAY_FIELDS:
202                form_fields = form_fields.omit(field)
203        form_fields['perm_address'].custom_widget = BytesDisplayWidget
204        form_fields['notice'].custom_widget = BytesDisplayWidget
205        if not getattr(self.context, 'student_id'):
206            form_fields = form_fields.omit('student_id')
207        if not getattr(self.context, 'screening_score'):
208            form_fields = form_fields.omit('screening_score')
209        if not getattr(self.context, 'screening_venue'):
210            form_fields = form_fields.omit('screening_venue')
211        if not getattr(self.context, 'screening_date'):
212            form_fields = form_fields.omit('screening_date')
213        return form_fields
214
215class CustomPDFActionButton(PDFActionButton):
216
217    @property
218    def target_url(self):
219        if self.context.state in ('initialized', 'started', 'paid') \
220            or self.context.special or self.view.target == 'trans':
221            return
222        return self.view.url(self.view.context, self.target)
223
224
225class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
226
227    column_two_fields = ('applicant_id', 'reg_number',
228        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
229    #two_columns_design_fields = [
230    #    'fst_sit_fname', 'fst_sit_no', 'fst_sit_date',
231    #    'fst_sit_type', 'fst_sit_results',
232    #    'scd_sit_fname', 'scd_sit_no', 'scd_sit_date',
233    #    'scd_sit_type', 'scd_sit_results']
234
235    @property
236    def note(self):
237        if self.context.sex == 'm':
238            pronoun = 'he'
239        else:
240            pronoun = 'she'
241        return '''
242The applicant has acknowledged that, if discovered at any time that %s does not possess
243any of the qualifications which %s claims %s has obtained, %s will be expelled from the
244University not be re-admitted for the same or any other programme, even if %s has
245upgraded previous and shall qualifications or possess additional qualifications.
246''' % (
247    pronoun, pronoun, pronoun, pronoun, pronoun)
248
249    @property
250    def form_fields(self):
251        # AAUE is using the same interface for all regular applications.
252        form_fields = grok.AutoFields(ICustomUGApplicant)
253        if self.target is not None and self.target.startswith('pg'):
254            for field in PG_OMIT_PDF_FIELDS:
255                form_fields = form_fields.omit(field)
256        elif self.target is not None and self.target in ('ptee', 'ude'):
257            for field in PTEE_OMIT_PDF_FIELDS:
258                form_fields = form_fields.omit(field)
259        else:
260            for field in UG_OMIT_PDF_FIELDS:
261                form_fields = form_fields.omit(field)
262        if not getattr(self.context, 'student_id'):
263            form_fields = form_fields.omit('student_id')
264        if not getattr(self.context, 'screening_score'):
265            form_fields = form_fields.omit('screening_score')
266        if not getattr(self.context, 'screening_venue'):
267            form_fields = form_fields.omit('screening_venue')
268        if not getattr(self.context, 'screening_date'):
269            form_fields = form_fields.omit('screening_date')
270        return form_fields
271
272class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
273    """A full edit view for applicant data.
274    """
275
276    @property
277    def form_fields(self):
278        if self.target is not None and self.target == 'trans':
279            form_fields = grok.AutoFields(ITranscriptApplicant)
280            form_fields['applicant_id'].for_display = True
281            return form_fields
282        # AAUE is using the same interface for all regular applications.
283        form_fields = grok.AutoFields(ICustomUGApplicant)
284        if self.target is not None and self.target.startswith('pg'):
285            for field in PG_OMIT_MANAGE_FIELDS:
286                form_fields = form_fields.omit(field)
287        elif self.target is not None and self.target in ('ptee', 'ude'):
288            for field in PTEE_OMIT_MANAGE_FIELDS:
289                form_fields = form_fields.omit(field)
290        else:
291            for field in UG_OMIT_MANAGE_FIELDS:
292                form_fields = form_fields.omit(field)
293        form_fields['student_id'].for_display = True
294        form_fields['applicant_id'].for_display = True
295        return form_fields
296
297class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
298    """An applicant-centered edit view for applicant data.
299    """
300
301    grok.template('applicanteditpage')
302
303    @property
304    def form_fields(self):
305        if self.target is not None and self.target == 'trans':
306            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
307                'locked', 'suspended')
308            form_fields['applicant_id'].for_display = True
309            return form_fields
310        # AAUE is using the same interface for all regular applications.
311        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
312        if self.target is not None and self.target.startswith('pg'):
313            for field in PG_OMIT_EDIT_FIELDS:
314                form_fields = form_fields.omit(field)
315        elif self.target is not None and self.target in ('ptee', 'ude'):
316            for field in PTEE_OMIT_EDIT_FIELDS:
317                form_fields = form_fields.omit(field)
318        else:
319            for field in UG_OMIT_EDIT_FIELDS:
320                form_fields = form_fields.omit(field)
321        form_fields['applicant_id'].for_display = True
322        form_fields['reg_number'].for_display = True
323        return form_fields
324
325class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
326    """Captcha'd registration page for applicants.
327    """
328
329    def _redirect(self, email, password, applicant_id):
330        # Forward email and credentials to landing page.
331        self.redirect(self.url(self.context, 'registration_complete',
332            data = dict(email=email, password=password,
333            applicant_id=applicant_id)))
334        return
335
336class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
337
338    @property
339    def payment_slip_download_warning(self):
340        return ''
341
342class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
343    """Captcha'd status checking page for applicants.
344    """
345    grok.template('applicantcheckstatus')
346
347class PaymentReceiptActionButton(ManageActionButton):
348    grok.order(8) # This button should always be the last one.
349    grok.context(ICustomApplicant)
350    grok.view(CustomApplicantDisplayFormPage)
351    grok.require('waeup.viewApplication')
352    icon = 'actionicon_pdf.png'
353    text = _('Download screening invitation letter')
354    target = 'screening_invitation.pdf'
355
356    @property
357    def target_url(self):
358        if not self.context.screening_date:
359            return ''
360        return self.view.url(self.view.context, self.target)
361
362class ExportScreeningInvitationLetter(UtilityView, grok.View):
363    """Deliver a slip with only screening data.
364    This form page is available only in AAUE.
365    """
366    grok.context(ICustomApplicant)
367    grok.name('screening_invitation.pdf')
368    grok.require('waeup.viewApplication')
369    prefix = 'form'
370
371    label = u'Screening Invitation Letter'
372
373    form_fields = []
374
375    @property
376    def note(self):
377        if self.context.screening_date:
378            year = self.context.__parent__.year
379            session = '%s/%s' % (year, year + 1)
380            sdate = self.context.screening_date
381            stime = ''
382            if '@' in self.context.screening_date:
383                sdate = self.context.screening_date.split('@')[0].strip()
384                stime = self.context.screening_date.split('@')[1].strip()
385            return """
386<br /><br /><br /><br /><font size='12'>
387Dear %s,
388<br /><br />
389You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
390<br /><br />
391<strong>Date: %s
392<br /><br />
393Time: %s
394<br /><br />
395Venue: %s
396</strong>
397<br /><br />
398Please bring this letter of invitation and the downloaded application form along with you on your screening date.
399<br /><br />
400You are expected to be available 30 minutes before the commencement of your Screening.
401</font>
402
403""" % (
404       self.context.display_fullname,
405       session,
406       sdate,
407       stime,
408       self.context.screening_venue)
409        return
410
411    @property
412    def title(self):
413        return None
414
415    def update(self):
416        if not self.context.screening_date:
417            self.flash(_('Forbidden'), type="warning")
418            self.redirect(self.url(self.context))
419
420    def render(self):
421        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
422        students_utils = getUtility(IStudentsUtils)
423        return students_utils.renderPDF(self,'screening_data.pdf',
424            self.context, applicantview, note=self.note)
Note: See TracBrowser for help on using the repository browser.