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

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

The locked field must be managable.

  • Property svn:keywords set to Id
File size: 14.7 KB
Line 
1## $Id: browser.py 16209 2020-08-19 13:51:12Z 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 = ('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                form_fields = form_fields.omit('locked')
320            return form_fields
321        if self.target is not None and self.target == 'tscs':
322            form_fields = grok.AutoFields(ITranscriptApplicant)
323            for field in TRANS_SHORT_OMIT_FIELDS:
324                form_fields = form_fields.omit(field)
325                form_fields = form_fields.omit('locked')
326            return form_fields
327        self.course_selector = True
328        if self.target is not None and self.target.startswith('pg'):
329            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
330            for field in PG_OMIT_EDIT_FIELDS:
331                form_fields = form_fields.omit(field)
332        else:
333            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
334            for field in UG_OMIT_EDIT_FIELDS:
335                form_fields = form_fields.omit(field)
336        form_fields['applicant_id'].for_display = True
337        form_fields['reg_number'].for_display = True
338        return form_fields
339
340class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
341
342    @property
343    def form_fields(self):
344        if self.target is not None and self.target.startswith('pg'):
345            form_fields = grok.AutoFields(ICustomPGApplicant)
346            for field in PG_OMIT_PDF_FIELDS:
347                form_fields = form_fields.omit(field)
348        else:
349            form_fields = grok.AutoFields(ICustomUGApplicant)
350            for field in UG_OMIT_PDF_FIELDS:
351                form_fields = form_fields.omit(field)
352        if not getattr(self.context, 'student_id'):
353            form_fields = form_fields.omit('student_id')
354        if not getattr(self.context, 'screening_score'):
355            form_fields = form_fields.omit('screening_score')
356        if not getattr(self.context, 'screening_venue'):
357            form_fields = form_fields.omit('screening_venue')
358        if not getattr(self.context, 'screening_date'):
359            form_fields = form_fields.omit('screening_date')
360        return form_fields
361
362class RefereeReportAddFormPage(RefereeReportAddFormPage):
363    """Add-form to add an referee report. This form
364    is protected by a mandate.
365    """
366    form_fields = grok.AutoFields(
367        ICustomApplicantRefereeReport).omit('creation_date')
368
369class CustomRefereeReportDisplayFormPage(RefereeReportDisplayFormPage):
370    """A display view for referee reports.
371    """
372    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
373    form_fields[
374        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
375
376
377class CustomExportPDFReportSlipPage(ExportPDFReportSlipPage):
378    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
379    form_fields[
380        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
381
382class CustomExportPDFReportSlipPage2(ExportPDFReportSlipPage2):
383    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
384    form_fields[
385        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
386
387class ResultStatement(AdditionalFile):
388    grok.name('res_stat.pdf')
389
390class JAMBResult(AdditionalFile):
391    grok.name('jamb.pdf')
392
393class FirstSitting(AdditionalFile):
394    grok.name('fst_sit_scan.pdf')
395
396class SecondSitting(AdditionalFile):
397    grok.name('scd_sit_scan.pdf')
398
399class HighQual(AdditionalFile):
400    grok.name('hq_scan.pdf')
401
402class AdvancedLevelResult(AdditionalFile):
403    grok.name('alr_scan.pdf')
404
405class NYSCCertificate(AdditionalFile):
406    grok.name('nysc.pdf')
Note: See TracBrowser for help on using the repository browser.