source: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/applicants/browser.py @ 16961

Last change on this file since 16961 was 16961, checked in by Henrik Bettermann, 2 years ago

Customize _finalsubmit_msg

  • Property svn:keywords set to Id
File size: 17.4 KB
Line 
1## $Id: browser.py 16961 2022-06-14 10:29:42Z 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, queryUtility
23from zope.catalog.interfaces import ICatalog
24from zope.formlib.textwidgets import BytesDisplayWidget
25from waeup.kofa.interfaces import (
26    IExtFileStore, IFileStoreNameChooser)
27from waeup.kofa.utils.helpers import string_from_bytes, file_size, now
28from waeup.kofa.applicants.browser import (
29    ApplicantRegistrationPage, ApplicantsContainerPage, AdditionalFile,
30    RefereeReportAddFormPage, ExportPDFReportSlipPage, ExportPDFReportSlipPage2,
31    RefereeReportDisplayFormPage,
32    ApplicantsContainerManageFormPage,
33    ApplicantAddFormPage)
34from waeup.kofa.applicants.interfaces import (
35    ISpecialApplicant, IApplicantsContainer, AppCatCertificateSource)
36from kofacustom.nigeria.applicants.browser import (
37    NigeriaApplicantDisplayFormPage,
38    NigeriaApplicantManageFormPage,
39    NigeriaApplicantEditFormPage,
40    NigeriaPDFApplicationSlip)
41from waeup.kofa.widgets.datewidget import (
42    FriendlyDateDisplayWidget,
43    FriendlyDatetimeDisplayWidget)
44from kofacustom.nigeria.applicants.interfaces import (
45    OMIT_DISPLAY_FIELDS,
46    #UG_OMIT_DISPLAY_FIELDS,
47    #UG_OMIT_PDF_FIELDS,
48    #UG_OMIT_MANAGE_FIELDS,
49    #UG_OMIT_EDIT_FIELDS,
50    #PG_OMIT_DISPLAY_FIELDS,
51    #PG_OMIT_PDF_FIELDS,
52    #PG_OMIT_MANAGE_FIELDS,
53    #PG_OMIT_EDIT_FIELDS,
54    )
55from kofacustom.iuokada.applicants.interfaces import (
56    ICustomPGApplicant, ICustomUGApplicant, ICustomApplicant,
57    ICustomPGApplicantEdit, ICustomUGApplicantEdit,
58    ICustomApplicantOnlinePayment, ICustomApplicantRefereeReport,
59    ITranscriptApplicant, ICustomApplicantRegisterUpdate
60    )
61from kofacustom.iuokada.interfaces import MessageFactory as _
62
63MAX_FILE_UPLOAD_SIZE = 1024 * 500
64
65# UG students are all undergraduate students.
66UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
67    #'jamb_subjects_list',
68    'programme_type',)
69UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + ('phone',)
70UG_OMIT_MANAGE_FIELDS = (
71    'special_application',
72    #'jamb_subjects_list',
73    'programme_type',
74    'course1',
75    'course2',)
76UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
77    'student_id',
78    'notice',
79    'screening_score',
80    'screening_venue',
81    'screening_date',
82    #'jamb_age',
83    #'jamb_subjects',
84    #'jamb_score',
85    #'jamb_reg_number',
86    'aggregate',
87    )
88
89JUPEB_OMIT_FIELDS = (
90    'jamb_age',
91    'jamb_subjects',
92    'jamb_score',
93    'jamb_reg_number',
94    'jamb_subjects_list',
95    'jamb_fname',
96    )
97
98# PG has its own interface
99PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
100    'employer',
101    'emp_position',
102    'emp_start',
103    'emp_end',
104    'emp_reason',
105    'employer2',
106    'emp2_position',
107    'emp2_start',
108    'emp2_end',
109    'emp2_reason',
110    )
111PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + ('phone',)
112PG_OMIT_MANAGE_FIELDS = (
113    'special_application',
114    'employer',
115    'emp_position',
116    'emp_start',
117    'emp_end',
118    'emp_reason',
119    'employer2',
120    'emp2_position',
121    'emp2_start',
122    'emp2_end',
123    'emp2_reason',
124    'course1',
125    'course2',
126    )
127PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + PG_OMIT_DISPLAY_FIELDS + (
128    'student_id',
129    'notice',
130    'screening_score',
131    'screening_venue',
132    'screening_date',)
133
134TRANS_OMIT_FIELDS = ('suspended', 'applicant_id',)
135
136TRANS_SHORT_OMIT_FIELDS = TRANS_OMIT_FIELDS + (
137    #'date_of_birth',
138    'sex',
139    'nationality',
140    #'entry_mode',
141    #'entry_session',
142    'end_session',
143    #'course_studied',
144    #'course_changed',
145    #'change_level',
146    )
147
148class CustomApplicantsContainerPage(ApplicantsContainerPage):
149    """The standard view for regular applicant containers.
150    """
151
152    @property
153    def form_fields(self):
154        form_fields = grok.AutoFields(IApplicantsContainer).omit(
155            'title', 'description')
156        if self.request.principal.id == 'zope.anybody':
157            form_fields = form_fields.omit(
158                'code', 'prefix', 'year', 'mode', 'hidden',
159                'strict_deadline', 'application_category',
160                'application_slip_notice',
161                'application_fee', 'with_picture',
162                'startdate', 'enddate')
163        return form_fields
164
165class CustomApplicantsContainerManageFormPage(ApplicantsContainerManageFormPage):
166
167    max_applicants = 3000
168
169class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
170    """A display view for applicant data.
171    """
172
173    @property
174    def form_fields(self):
175        if self.target is not None and self.target == 'tscf':
176            form_fields = grok.AutoFields(ITranscriptApplicant)
177            for field in TRANS_OMIT_FIELDS:
178                form_fields = form_fields.omit(field)
179            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
180            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
181            return form_fields
182        if self.target is not None and self.target == 'tscs':
183            form_fields = grok.AutoFields(ITranscriptApplicant)
184            for field in TRANS_SHORT_OMIT_FIELDS:
185                form_fields = form_fields.omit(field)
186            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
187            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
188            return form_fields
189        if self.target is not None and self.target.startswith('pg'):
190            form_fields = grok.AutoFields(ICustomPGApplicant)
191            for field in PG_OMIT_DISPLAY_FIELDS:
192                form_fields = form_fields.omit(field)
193        else:
194            form_fields = grok.AutoFields(ICustomUGApplicant)
195            for field in UG_OMIT_DISPLAY_FIELDS:
196                form_fields = form_fields.omit(field)
197        if self.target is not None and self.target == 'pre':
198            for field in JUPEB_OMIT_FIELDS:
199                form_fields = form_fields.omit(field)
200        #form_fields['perm_address'].custom_widget = BytesDisplayWidget
201        form_fields['notice'].custom_widget = BytesDisplayWidget
202        if not getattr(self.context, 'student_id'):
203            form_fields = form_fields.omit('student_id')
204        if not getattr(self.context, 'screening_score'):
205            form_fields = form_fields.omit('screening_score')
206        if not getattr(self.context, 'screening_venue') or self._not_paid():
207            form_fields = form_fields.omit('screening_venue')
208        if not getattr(self.context, 'screening_date') or self._not_paid():
209            form_fields = form_fields.omit('screening_date')
210        return form_fields
211
212def getCerts(view, coursex):
213    yield(dict(code='', title='--', selected=''))
214    appcatcertificatesource = AppCatCertificateSource().factory
215    for cert in appcatcertificatesource.getValues(view.context):
216        selected = ''
217        course = getattr(view.context, coursex)
218        if course is not None and course.code == cert.code:
219            selected = 'selected'
220        title = appcatcertificatesource.getTitle(view.context, cert)
221        yield(dict(code=cert.code, title=title, selected=selected))
222
223def saveCourses(view):
224    """In custom packages we needed to customize the certificate
225    select widget. We just save course1 and course2 if these customized
226    fields appear in the form.
227    """
228    changed_courses = []
229    form = view.request.form
230    course1 = form.get('custom.course1', None)
231    if not course1:
232        return 'Please select your 1st Choice Course of Study.', None
233    cat = queryUtility(ICatalog, name='certificates_catalog')
234    results = list(
235        cat.searchResults(code=(course1, course1)))
236    new_course1 = results[0]
237    old_course1 = view.context.course1
238    if old_course1 != new_course1:
239        view.context.course1 = new_course1
240        changed_courses.append('course1')
241    new_course2 = None
242    old_course2 = view.context.course2
243    course2 = form.get('custom.course2', None)
244    if course2:
245        results = list(
246            cat.searchResults(code=(course2, course2)))
247        new_course2 = results[0]
248    if old_course2 != new_course2:
249        view.context.course2 = new_course2
250        changed_courses.append('course2')
251    return None, changed_courses
252
253def display_fileupload(view, filename):
254    if view.target.startswith('tsc'):
255        return False
256    if filename[1] == 'res_stat.pdf':
257        if view.context.subtype != 'transfer':
258            return False
259    if filename[1] == 'jamb.pdf' \
260        and view.target is not None \
261        and view.target.startswith('pg'):
262        return False
263    if filename[1] == 'nysc.pdf' \
264        and view.target is not None \
265        and not view.target.startswith('pg'):
266        return False
267    return True
268
269class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
270    """A full edit view for applicant data.
271    """
272
273    def getCerts(self, coursex):
274        return getCerts(self, coursex)
275
276    def saveCourses(self):
277        return saveCourses(self)
278
279    def display_fileupload(self, filename):
280        return display_fileupload(self, filename)
281
282    @property
283    def display_refereereports(self):
284        if self.context.refereereports:
285            return True
286        return False
287
288    @property
289    def form_fields(self):
290        self.course_selector = False
291        if self.target is not None and self.target == 'tscf':
292            form_fields = grok.AutoFields(ITranscriptApplicant)
293            for field in TRANS_OMIT_FIELDS:
294                form_fields = form_fields.omit(field)
295            return form_fields
296        if self.target is not None and self.target == 'tscs':
297            form_fields = grok.AutoFields(ITranscriptApplicant)
298            for field in TRANS_SHORT_OMIT_FIELDS:
299                form_fields = form_fields.omit(field)
300            return form_fields
301        self.course_selector = True
302        if self.target is not None and self.target.startswith('pg'):
303            form_fields = grok.AutoFields(ICustomPGApplicant)
304            for field in PG_OMIT_MANAGE_FIELDS:
305                form_fields = form_fields.omit(field)
306        else:
307            form_fields = grok.AutoFields(ICustomUGApplicant)
308            for field in UG_OMIT_MANAGE_FIELDS:
309                form_fields = form_fields.omit(field)
310        if self.target is not None and self.target == 'pre':
311            for field in JUPEB_OMIT_FIELDS:
312                form_fields = form_fields.omit(field)
313        form_fields['student_id'].for_display = True
314        form_fields['applicant_id'].for_display = True
315        return form_fields
316
317class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
318    """An applicant-centered edit view for applicant data.
319    """
320
321    def getCerts(self, coursex):
322        return getCerts(self, coursex)
323
324    def saveCourses(self):
325        return saveCourses(self)
326
327    def display_fileupload(self, filename):
328        return display_fileupload(self, filename)
329
330    @property
331    def _finalsubmit_msg(self):
332        if self.context.subtype in ('transfer', 'de'):
333            return 'Form has been submitted. Please note: DE and Transfer applicants are to present their application form and the proof of JAMB local transfer form at the admissions office for application approval.'
334        return _('Form has been submitted.')
335
336    def dataNotComplete(self, data):
337        store = getUtility(IExtFileStore)
338        if self.context.subtype \
339            and self.context.subtype not in ('transfer', 'de', 'jupeb') \
340            and (not self.context.jamb_fname
341                 or not self.context.jamb_reg_number):
342            return _('JAMB fields must be filled.')
343        if self.context.subtype in ('transfer', 'de') \
344            and not self.context.ref_number:
345            return _('Reference Number field must be filled.')
346        if self.context.__parent__.with_picture:
347            store = getUtility(IExtFileStore)
348            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
349                return _('No passport picture uploaded.')
350        if self.context.subtype == 'transfer' \
351            and self.context.__parent__.code!= 'ug2020' \
352            and not store.getFileByContext(self.context, attr=u'res_stat.pdf'):
353            return _('No statement of result pdf file uploaded.')
354        return False
355
356    @property
357    def form_fields(self):
358        self.course_selector = False
359        if self.target is not None and self.target == 'tscf':
360            form_fields = grok.AutoFields(ITranscriptApplicant)
361            for field in TRANS_OMIT_FIELDS:
362                form_fields = form_fields.omit(field)
363                form_fields = form_fields.omit('locked')
364            return form_fields
365        if self.target is not None and self.target == 'tscs':
366            form_fields = grok.AutoFields(ITranscriptApplicant)
367            for field in TRANS_SHORT_OMIT_FIELDS:
368                form_fields = form_fields.omit(field)
369                form_fields = form_fields.omit('locked')
370            return form_fields
371        self.course_selector = True
372        if self.target is not None and self.target.startswith('pg'):
373            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
374            for field in PG_OMIT_EDIT_FIELDS:
375                form_fields = form_fields.omit(field)
376        else:
377            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
378            for field in UG_OMIT_EDIT_FIELDS:
379                form_fields = form_fields.omit(field)
380        if self.target is not None and self.target == 'pre':
381            for field in JUPEB_OMIT_FIELDS:
382                form_fields = form_fields.omit(field)
383        form_fields['applicant_id'].for_display = True
384        form_fields['reg_number'].for_display = True
385        return form_fields
386
387class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
388
389    @property
390    def form_fields(self):
391        if self.target is not None and self.target.startswith('pg'):
392            form_fields = grok.AutoFields(ICustomPGApplicant)
393            for field in PG_OMIT_PDF_FIELDS:
394                form_fields = form_fields.omit(field)
395        else:
396            form_fields = grok.AutoFields(ICustomUGApplicant)
397            for field in UG_OMIT_PDF_FIELDS:
398                form_fields = form_fields.omit(field)
399        if not getattr(self.context, 'student_id'):
400            form_fields = form_fields.omit('student_id')
401        if not getattr(self.context, 'screening_score'):
402            form_fields = form_fields.omit('screening_score')
403        if not getattr(self.context, 'screening_venue'):
404            form_fields = form_fields.omit('screening_venue')
405        if not getattr(self.context, 'screening_date'):
406            form_fields = form_fields.omit('screening_date')
407        return form_fields
408
409class CustomApplicantRegistrationPage(ApplicantRegistrationPage):
410    """Captcha'd registration page for applicants.
411    """
412    @property
413    def form_fields(self):
414        form_fields = None
415        if self.context.mode == 'update':
416            form_fields = grok.AutoFields(ICustomApplicantRegisterUpdate).select(
417                'lastname','reg_number','email')
418        else: #if self.context.mode == 'create':
419            form_fields = grok.AutoFields(ICustomUGApplicant).select(
420                'firstname', 'middlename', 'lastname', 'email', 'phone')
421        return form_fields
422
423class CustomApplicantAddFormPage(ApplicantAddFormPage):
424    """Add-form to add an applicant.
425    """
426    form_fields = grok.AutoFields(ICustomApplicant).select(
427        'firstname', 'middlename', 'lastname',
428        'email', 'phone')
429
430class RefereeReportAddFormPage(RefereeReportAddFormPage):
431    """Add-form to add an referee report. This form
432    is protected by a mandate.
433    """
434    form_fields = grok.AutoFields(
435        ICustomApplicantRefereeReport).omit('creation_date')
436
437class CustomRefereeReportDisplayFormPage(RefereeReportDisplayFormPage):
438    """A display view for referee reports.
439    """
440    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
441    form_fields[
442        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
443
444
445class CustomExportPDFReportSlipPage(ExportPDFReportSlipPage):
446    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
447    form_fields[
448        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
449
450class CustomExportPDFReportSlipPage2(ExportPDFReportSlipPage2):
451    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
452    form_fields[
453        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
454
455class ResultStatement(AdditionalFile):
456    grok.name('res_stat')
457
458class JAMBResult(AdditionalFile):
459    grok.name('jamb')
460
461class FirstSitting(AdditionalFile):
462    grok.name('fst_sit_scan')
463
464class SecondSitting(AdditionalFile):
465    grok.name('scd_sit_scan')
466
467class HighQual(AdditionalFile):
468    grok.name('hq_scan')
469
470class AdvancedLevelResult(AdditionalFile):
471    grok.name('alr_scan')
472
473class NYSCCertificate(AdditionalFile):
474    grok.name('nysc')
475
476class PaymentReceipts(AdditionalFile):
477    grok.name('rmp')
Note: See TracBrowser for help on using the repository browser.