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

Last change on this file since 16165 was 16165, checked in by Henrik Bettermann, 4 years ago

Configure transcript applications.

  • Property svn:keywords set to Id
File size: 14.6 KB
Line 
1## $Id: browser.py 16165 2020-07-14 14:19:29Z 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)
32from waeup.kofa.applicants.interfaces import (
33    ISpecialApplicant, IApplicantsContainer, AppCatCertificateSource)
34from kofacustom.nigeria.applicants.browser import (
35    NigeriaApplicantDisplayFormPage,
36    NigeriaApplicantManageFormPage,
37    NigeriaApplicantEditFormPage,
38    NigeriaPDFApplicationSlip)
39from waeup.kofa.widgets.datewidget import (
40    FriendlyDateDisplayWidget,
41    FriendlyDatetimeDisplayWidget)
42from kofacustom.nigeria.applicants.interfaces import (
43    OMIT_DISPLAY_FIELDS,
44    #UG_OMIT_DISPLAY_FIELDS,
45    #UG_OMIT_PDF_FIELDS,
46    #UG_OMIT_MANAGE_FIELDS,
47    #UG_OMIT_EDIT_FIELDS,
48    #PG_OMIT_DISPLAY_FIELDS,
49    #PG_OMIT_PDF_FIELDS,
50    #PG_OMIT_MANAGE_FIELDS,
51    #PG_OMIT_EDIT_FIELDS,
52    )
53from kofacustom.iuokada.applicants.interfaces import (
54    ICustomPGApplicant, ICustomUGApplicant, ICustomApplicant,
55    ICustomPGApplicantEdit, ICustomUGApplicantEdit,
56    ICustomApplicantOnlinePayment, ICustomApplicantRefereeReport,
57    ITranscriptApplicant
58    )
59from kofacustom.iuokada.interfaces import MessageFactory as _
60
61MAX_FILE_UPLOAD_SIZE = 1024 * 500
62
63# UG students are all undergraduate students.
64UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
65    #'jamb_subjects_list',
66    'programme_type',)
67UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + ('phone',)
68UG_OMIT_MANAGE_FIELDS = (
69    'special_application',
70    #'jamb_subjects_list',
71    'programme_type',
72    'course1',
73    'course2',)
74UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
75    'student_id',
76    'notice',
77    'screening_score',
78    'screening_venue',
79    'screening_date',
80    #'jamb_age',
81    #'jamb_subjects',
82    #'jamb_score',
83    #'jamb_reg_number',
84    'aggregate',
85    )
86
87# PG has its own interface
88PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
89    'employer',
90    'emp_position',
91    'emp_start',
92    'emp_end',
93    'emp_reason',
94    'employer2',
95    'emp2_position',
96    'emp2_start',
97    'emp2_end',
98    'emp2_reason',
99    )
100PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + ('phone',)
101PG_OMIT_MANAGE_FIELDS = (
102    'special_application',
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    'course1',
114    'course2',
115    )
116PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + PG_OMIT_DISPLAY_FIELDS + (
117    'student_id',
118    'notice',
119    'screening_score',
120    'screening_venue',
121    'screening_date',)
122
123TRANS_OMIT_FIELDS = ('locked', 'suspended', 'applicant_id',)
124
125TRANS_SHORT_OMIT_FIELDS = TRANS_OMIT_FIELDS + (
126    #'date_of_birth',
127    'sex',
128    'nationality',
129    #'entry_mode',
130    #'entry_session',
131    'end_session',
132    #'course_studied',
133    #'course_changed',
134    #'change_level',
135    )
136
137class CustomApplicantsContainerPage(ApplicantsContainerPage):
138    """The standard view for regular applicant containers.
139    """
140
141    @property
142    def form_fields(self):
143        form_fields = grok.AutoFields(IApplicantsContainer).omit(
144            'title', 'description')
145        if self.request.principal.id == 'zope.anybody':
146            form_fields = form_fields.omit(
147                'code', 'prefix', 'year', 'mode', 'hidden',
148                'strict_deadline', 'application_category',
149                'application_slip_notice',
150                'application_fee', 'with_picture',
151                'startdate', 'enddate')
152        return form_fields
153
154class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
155    """A display view for applicant data.
156    """
157
158    @property
159    def form_fields(self):
160        if self.target is not None and self.target == 'tscf':
161            form_fields = grok.AutoFields(ITranscriptApplicant)
162            for field in TRANS_OMIT_FIELDS:
163                form_fields = form_fields.omit(field)
164            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
165            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
166            return form_fields
167        if self.target is not None and self.target == 'tscs':
168            form_fields = grok.AutoFields(ITranscriptApplicant)
169            for field in TRANS_SHORT_OMIT_FIELDS:
170                form_fields = form_fields.omit(field)
171            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
172            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
173            return form_fields
174        if self.target is not None and self.target.startswith('pg'):
175            form_fields = grok.AutoFields(ICustomPGApplicant)
176            for field in PG_OMIT_DISPLAY_FIELDS:
177                form_fields = form_fields.omit(field)
178        else:
179            form_fields = grok.AutoFields(ICustomUGApplicant)
180            for field in UG_OMIT_DISPLAY_FIELDS:
181                form_fields = form_fields.omit(field)
182        #form_fields['perm_address'].custom_widget = BytesDisplayWidget
183        form_fields['notice'].custom_widget = BytesDisplayWidget
184        if not getattr(self.context, 'student_id'):
185            form_fields = form_fields.omit('student_id')
186        if not getattr(self.context, 'screening_score'):
187            form_fields = form_fields.omit('screening_score')
188        if not getattr(self.context, 'screening_venue') or self._not_paid():
189            form_fields = form_fields.omit('screening_venue')
190        if not getattr(self.context, 'screening_date') or self._not_paid():
191            form_fields = form_fields.omit('screening_date')
192        return form_fields
193
194def getCerts(view, coursex):
195    yield(dict(code='', title='--', selected=''))
196    appcatcertificatesource = AppCatCertificateSource().factory
197    for cert in appcatcertificatesource.getValues(view.context):
198        selected = ''
199        course = getattr(view.context, coursex)
200        if course is not None and course.code == cert.code:
201            selected = 'selected'
202        title = appcatcertificatesource.getTitle(view.context, cert)
203        yield(dict(code=cert.code, title=title, selected=selected))
204
205def saveCourses(view, changed_fields=[]):
206    """In custom packages we needed to customize the certificate
207    select widget. We just save course1 and course2 if these customized
208    fields appear in the form.
209    """
210    form = view.request.form
211    course1 = form.get('custom.course1', None)
212    course2 = form.get('custom.course2', None)
213    cat = queryUtility(ICatalog, name='certificates_catalog')
214    if course1:
215        results = list(
216            cat.searchResults(code=(course1, course1)))
217        view.context.course1 = results[0]
218        changed_fields.append('course1')
219    if course2:
220        results = list(
221            cat.searchResults(code=(course2, course2)))
222        view.context.course2 = results[0]
223        changed_fields.append('course2')
224    return changed_fields
225
226def display_fileupload(view, filename):
227    if view.target.startswith('tsc'):
228        return False
229    if filename[1] == 'res_stat.pdf':
230        if view.context.subtype != 'transfer':
231            return False
232    if filename[1] == 'jamb.pdf' \
233        and view.target is not None \
234        and view.target.startswith('pg'):
235        return False
236    if filename[1] == 'nysc.pdf' \
237        and view.target is not None \
238        and not view.target.startswith('pg'):
239        return False
240    return True
241
242class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
243    """A full edit view for applicant data.
244    """
245
246    def getCerts(self, coursex):
247        return getCerts(self, coursex)
248
249    def saveCourses(self, changed_fields):
250        return saveCourses(self, changed_fields)
251
252    def display_fileupload(self, filename):
253        return display_fileupload(self, filename)
254
255    @property
256    def display_refereereports(self):
257        if self.context.refereereports:
258            return True
259        return False
260
261    @property
262    def form_fields(self):
263        self.course_selector = False
264        if self.target is not None and self.target == 'tscf':
265            form_fields = grok.AutoFields(ITranscriptApplicant)
266            for field in TRANS_OMIT_FIELDS:
267                form_fields = form_fields.omit(field)
268            return form_fields
269        if self.target is not None and self.target == 'tscs':
270            form_fields = grok.AutoFields(ITranscriptApplicant)
271            for field in TRANS_SHORT_OMIT_FIELDS:
272                form_fields = form_fields.omit(field)
273            return form_fields
274        self.course_selector = True
275        if self.target is not None and self.target.startswith('pg'):
276            form_fields = grok.AutoFields(ICustomPGApplicant)
277            for field in PG_OMIT_MANAGE_FIELDS:
278                form_fields = form_fields.omit(field)
279        else:
280            form_fields = grok.AutoFields(ICustomUGApplicant)
281            for field in UG_OMIT_MANAGE_FIELDS:
282                form_fields = form_fields.omit(field)
283        form_fields['student_id'].for_display = True
284        form_fields['applicant_id'].for_display = True
285        return form_fields
286
287class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
288    """An applicant-centered edit view for applicant data.
289    """
290
291    def getCerts(self, coursex):
292        return getCerts(self, coursex)
293
294    def saveCourses(self):
295        return saveCourses(self)
296
297    def display_fileupload(self, filename):
298        return display_fileupload(self, filename)
299
300    def dataNotComplete(self, data):
301        store = getUtility(IExtFileStore)
302        if self.context.__parent__.with_picture:
303            store = getUtility(IExtFileStore)
304            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
305                return _('No passport picture uploaded.')
306        if self.context.subtype == 'transfer' \
307            and self.context.__parent__.code!= 'ug2020' \
308            and not store.getFileByContext(self.context, attr=u'res_stat.pdf'):
309            return _('No statement of result pdf file uploaded.')
310        return False
311
312    @property
313    def form_fields(self):
314        self.course_selector = False
315        if self.target is not None and self.target == 'tscf':
316            form_fields = grok.AutoFields(ITranscriptApplicant)
317            for field in TRANS_OMIT_FIELDS:
318                form_fields = form_fields.omit(field)
319            return form_fields
320        if self.target is not None and self.target == 'tscs':
321            form_fields = grok.AutoFields(ITranscriptApplicant)
322            for field in TRANS_SHORT_OMIT_FIELDS:
323                form_fields = form_fields.omit(field)
324            return form_fields
325        self.course_selector = True
326        if self.target is not None and self.target.startswith('pg'):
327            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
328            for field in PG_OMIT_EDIT_FIELDS:
329                form_fields = form_fields.omit(field)
330        else:
331            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
332            for field in UG_OMIT_EDIT_FIELDS:
333                form_fields = form_fields.omit(field)
334        form_fields['applicant_id'].for_display = True
335        form_fields['reg_number'].for_display = True
336        return form_fields
337
338class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
339
340    @property
341    def form_fields(self):
342        if self.target is not None and self.target.startswith('pg'):
343            form_fields = grok.AutoFields(ICustomPGApplicant)
344            for field in PG_OMIT_PDF_FIELDS:
345                form_fields = form_fields.omit(field)
346        else:
347            form_fields = grok.AutoFields(ICustomUGApplicant)
348            for field in UG_OMIT_PDF_FIELDS:
349                form_fields = form_fields.omit(field)
350        if not getattr(self.context, 'student_id'):
351            form_fields = form_fields.omit('student_id')
352        if not getattr(self.context, 'screening_score'):
353            form_fields = form_fields.omit('screening_score')
354        if not getattr(self.context, 'screening_venue'):
355            form_fields = form_fields.omit('screening_venue')
356        if not getattr(self.context, 'screening_date'):
357            form_fields = form_fields.omit('screening_date')
358        return form_fields
359
360class RefereeReportAddFormPage(RefereeReportAddFormPage):
361    """Add-form to add an referee report. This form
362    is protected by a mandate.
363    """
364    form_fields = grok.AutoFields(
365        ICustomApplicantRefereeReport).omit('creation_date')
366
367class CustomRefereeReportDisplayFormPage(RefereeReportDisplayFormPage):
368    """A display view for referee reports.
369    """
370    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
371    form_fields[
372        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
373
374
375class CustomExportPDFReportSlipPage(ExportPDFReportSlipPage):
376    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
377    form_fields[
378        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
379
380class CustomExportPDFReportSlipPage2(ExportPDFReportSlipPage2):
381    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
382    form_fields[
383        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
384
385class ResultStatement(AdditionalFile):
386    grok.name('res_stat.pdf')
387
388class JAMBResult(AdditionalFile):
389    grok.name('jamb.pdf')
390
391class FirstSitting(AdditionalFile):
392    grok.name('fst_sit_scan.pdf')
393
394class SecondSitting(AdditionalFile):
395    grok.name('scd_sit_scan.pdf')
396
397class HighQual(AdditionalFile):
398    grok.name('hq_scan.pdf')
399
400class AdvancedLevelResult(AdditionalFile):
401    grok.name('alr_scan.pdf')
402
403class NYSCCertificate(AdditionalFile):
404    grok.name('nysc.pdf')
Note: See TracBrowser for help on using the repository browser.