source: main/waeup.uniben/trunk/src/waeup/uniben/applicants/browser.py @ 17720

Last change on this file since 17720 was 17597, checked in by Henrik Bettermann, 14 months ago

Set required fields in views not in interfaces.

  • Property svn:keywords set to Id
File size: 39.7 KB
RevLine 
[8012]1## $Id: browser.py 17597 2023-09-28 07:36:15Z 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"""
[10287]20import grok
[11784]21from time import time
[11782]22from zope.component import getUtility, createObject
[14105]23from zope.formlib.textwidgets import BytesDisplayWidget
[11736]24from zope.security import checkPermission
[13552]25from zope.i18n import translate
[11784]26from hurry.workflow.interfaces import IWorkflowState
27from waeup.kofa.browser.layout import action, UtilityView
[13552]28from waeup.kofa.interfaces import IExtFileStore, IKofaUtils
[10587]29from waeup.kofa.applicants.browser import (
[11728]30    ApplicantRegistrationPage, ApplicantsContainerPage,
[11782]31    ApplicationFeePaymentAddPage,
[11784]32    OnlinePaymentApprovePage,
[14147]33    ExportPDFPageApplicationSlip,
[16117]34    ApplicantBaseDisplayFormPage,
[16164]35    CheckTranscriptStatus,
[16504]36    AdditionalFile,)
[14147]37from waeup.kofa.students.interfaces import IStudentsUtils
[11782]38from waeup.kofa.applicants.interfaces import (
39    ISpecialApplicant, IApplicantsUtils)
[13558]40from waeup.kofa.browser.interfaces import IPDFCreator
[10378]41from kofacustom.nigeria.applicants.browser import (
42    NigeriaApplicantDisplayFormPage,
[11736]43    NigeriaApplicantManageFormPage,
[13796]44    NigeriaApplicantEditFormPage,
[16504]45    NigeriaPDFApplicationSlip,
46    NigeriaExportPDFPaymentSlipPage)
[11782]47from waeup.uniben.applicants.interfaces import (
[14105]48    ICustomApplicant,
49    IUnibenRegistration,
50    ICustomUGApplicant,
51    ICustomPGApplicant,
52    ICustomPGApplicantEdit,
53    ICustomUGApplicantEdit,
[16078]54    IPUTMEApplicantEdit,
[16804]55    ITranscriptApplicant,
56    IFrenchApplicant)
[13825]57from waeup.kofa.applicants.workflow import ADMITTED, PAID, STARTED
[14105]58from kofacustom.nigeria.applicants.interfaces import (
[17537]59    OMIT_DISPLAY_FIELDS,
[17538]60    UG_OMIT_DISPLAY_FIELDS,
61    UG_OMIT_PDF_FIELDS,
62    UG_OMIT_MANAGE_FIELDS,
63    UG_OMIT_EDIT_FIELDS,
[14105]64    CBT_OMIT_DISPLAY_FIELDS,
65    CBT_OMIT_PDF_FIELDS,
66    CBT_OMIT_MANAGE_FIELDS,
67    CBT_OMIT_EDIT_FIELDS,
68    AFFIL_OMIT_DISPLAY_FIELDS,
69    AFFIL_OMIT_PDF_FIELDS,
70    AFFIL_OMIT_MANAGE_FIELDS,
71    AFFIL_OMIT_EDIT_FIELDS,
72    PG_OMIT_DISPLAY_FIELDS,
73    PG_OMIT_PDF_FIELDS,
74    PG_OMIT_MANAGE_FIELDS,
75    PG_OMIT_EDIT_FIELDS,
76    PUTME_OMIT_DISPLAY_FIELDS,
[17538]77    PUTME_OMIT_PDF_FIELDS,
78    PUTME_OMIT_MANAGE_FIELDS,
79    PUTME_OMIT_EDIT_FIELDS,
80    PUTME_OMIT_RESULT_SLIP_FIELDS,
[14105]81    PUDE_OMIT_DISPLAY_FIELDS,
82    PUDE_OMIT_PDF_FIELDS,
83    PUDE_OMIT_MANAGE_FIELDS,
84    PUDE_OMIT_EDIT_FIELDS,
85    PUDE_OMIT_RESULT_SLIP_FIELDS,
86    PRE_OMIT_DISPLAY_FIELDS,
87    PRE_OMIT_PDF_FIELDS,
88    PRE_OMIT_MANAGE_FIELDS,
89    PRE_OMIT_EDIT_FIELDS,
90    )
[8012]91
[10378]92from waeup.uniben.interfaces import MessageFactory as _
93
[14839]94PASTQ_ALL = ['ADT','CIT','DEF','DEM','EPCS','ESM','HEK','HSE','VTE']
[8012]95
[14839]96PASTQ_AL = ['ENL','FAA','FOL','HIS','LAL', 'PHL','THR','BUL','JIL',
97            'LAW','PPL','PUL'] + PASTQ_ALL
[10338]98
99PASTQ_BS = ['ANT','ANY','CHH','COH','HAE','MED','MEH','PHS','SUR',
100            'PCG','PCH','PCO', 'PCT','PHA','PHM','PMB','ANA','MBC',
101            'MLS','NSC','PSY','DPV','ODR','OSP','PER', 'RES','AEB',
102            'BCH','BOT','CED','EVL','MCB','OPT','PBB','SLT','ZOO',
103            'AEE','ANS', 'CRS','FIS','FOW','SOS'] + PASTQ_ALL
104
[14839]105PASTQ_EPS = ['ARC','CHE','CVE','DMIC','EEE','GEM','MCH','PEE','PRE','CHM',
[14850]106             'CSC','GLY','MTH','QSV','PHY','CPE','STR'] + PASTQ_ALL
[10338]107
[14848]108PASTQ_MSS = ['ACC','BNK','BUS','ECO','ESM','GEO','POL','SAA','SWK',
109             'ACT','ENT','HRM','INS','MKT'] + PASTQ_ALL
[10338]110
[17538]111PT_OMIT_FIELDS = (
[17537]112    'student_id',
113    'notice',
114    'screening_score',
115    'screening_venue',
116    'screening_date',
117    'jamb_age',
118    'jamb_subjects',
119    'jamb_score',
[17538]120    #'jamb_reg_number',
121    'aggregate',
[17537]122    'hq_type', 'hq_matric_no',
123    'hq_degree', 'hq_school',
124    'hq_session', 'hq_disc',
125    'jamb_subjects_list', 'programme_type')
126
[17538]127PT_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + PT_OMIT_FIELDS
[17537]128
[17538]129PT_OMIT_MANAGE_FIELDS = UG_OMIT_MANAGE_FIELDS + PT_OMIT_FIELDS
[17537]130
[17538]131PT_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + PT_OMIT_FIELDS
[17537]132
[17538]133PT_OMIT_PDF_FIELDS = PT_OMIT_DISPLAY_FIELDS + ('phone',)
134PT_OMIT_RESULT_SLIP_FIELDS = PT_OMIT_DISPLAY_FIELDS + (
[17537]135    'phone',
136    'date_of_birth', 'sex',
137    'nationality', 'lga', #'perm_address',
138    'course2', 'screening_venue',
139    'screening_date')
140
141
[13814]142REGISTRATION_OMIT_DISPLAY_FIELDS = (
143    'locked',
144    'suspended',
[16945]145    'course_admitted',
[13796]146    )
147
[13814]148REGISTRATION_OMIT_EDIT_FIELDS = (
149    'locked',
150    'suspended',
151    'applicant_id',
[16945]152    'course_admitted',
[13814]153    )
154
155REGISTRATION_OMIT_MANAGE_FIELDS = (
156    'applicant_id',
157    )
158
159
160REGISTRATION_OMIT_PDF_FIELDS = (
161    'locked',
162    'suspended',
[16945]163    'course_admitted',
[13814]164    )
[14848]165
166PUTME_OMIT_PDF_FIELDS = PUTME_OMIT_PDF_FIELDS + (
167    'fst_sit_results', 'scd_sit_results')
168
[16227]169TRANS_OMIT_FIELDS = ('suspended',)
[16131]170
[16331]171#TRANS_SHORT_OMIT_FIELDS = TRANS_OMIT_FIELDS + (
172#    'date_of_birth',
173#    'sex',
174#    #'nationality',
175#    'entry_mode',
176#    'entry_session',
177#    'end_session',
178#    'course_studied',
179#    'course_changed',
180#    #'change_level',
181#    )
[16131]182
[16331]183TRANS_SHORT_OMIT_FIELDS = TRANS_OMIT_FIELDS
184
[16227]185TRANS_OMIT_EDIT_FIELDS = TRANS_OMIT_FIELDS + ('applicant_id', )
186
187TRANS_SHORT_OMIT_EDIT_FIELDS = TRANS_SHORT_OMIT_FIELDS + ('applicant_id', )
188
189TRANS_OMIT_PDF_FIELDS = TRANS_OMIT_FIELDS + ('locked', )
190
191TRANS_SHORT_OMIT_PDF_FIELDS = TRANS_SHORT_OMIT_FIELDS + ('locked', )
192
[10587]193class CustomApplicantsContainerPage(ApplicantsContainerPage):
194    """The standard view for regular applicant containers.
195    """
196
197    @property
198    def form_fields(self):
199        form_fields = super(CustomApplicantsContainerPage, self).form_fields
[10589]200        usertype = getattr(self.request.principal, 'user_type', None)
201        if self.request.principal.id == 'zope.anybody' or  \
202            usertype in ('applicant', 'student'):
[10587]203            return form_fields.omit('application_fee')
204        return form_fields
205
[8630]206class CustomApplicantRegistrationPage(ApplicantRegistrationPage):
207    """Captcha'd registration page for applicants.
208    """
209
[10337]210    def _redirect(self, email, password, applicant_id):
211        # Forward email and credentials to landing page.
212        self.redirect(self.url(self.context, 'registration_complete',
213            data = dict(email=email, password=password,
214            applicant_id=applicant_id)))
215        return
[10287]216
[16175]217    @property
218    def label(self):
219        if self.context.prefix.startswith('tsc'):
220            return _('Request for ${a}',
221                mapping = {'a':self.context.title})
222        return _('Apply for ${a}',
223            mapping = {'a':self.context.title})
224
[10375]225class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
226    """A display view for applicant data.
[10287]227    """
[10375]228    grok.template('applicantdisplaypage')
[10338]229
[13887]230    @property
231    def display_payments(self):
232        if self.context.special or self.target == 'ictwk':
233            return True
234        return getattr(self.context.__parent__, 'application_fee', None)
235
[10622]236    def _show_pastq_putme(self):
[15487]237        return self.target.startswith('pre') \
[14821]238               and self.context.state in ('paid', 'submitted') \
239               and getattr(self.context, 'course1') is not None
240        # return False
[10338]241
242    @property
[14090]243    def depcode(self):
244        try:
245            code = self.context.course1.__parent__.__parent__.code
246            return code
247        except:
248            return
249
250    @property
[10338]251    def show_pastq_al(self):
[15486]252        return self._show_pastq_putme() # and self.depcode in PASTQ_AL
[10338]253
254    @property
255    def show_pastq_bs(self):
[15486]256        return self._show_pastq_putme() # and self.depcode in PASTQ_BS
[10338]257
258    @property
259    def show_pastq_eps(self):
[15486]260        return self._show_pastq_putme() # and self.depcode in PASTQ_EPS
[10338]261
262    @property
263    def show_pastq_mss(self):
[15486]264        return self._show_pastq_putme() # and self.depcode in PASTQ_MSS
[10338]265
[10622]266    @property
267    def show_pastq_pude(self):
268        return self.target.startswith('pude') \
269               and self.context.state in ('paid', 'submitted')
270
[13814]271    @property
272    def label(self):
273        if self.target == 'ictwk':
274            container_title = self.context.__parent__.title
275            return _('${a} <br /> Registration Record ${b}', mapping = {
276                'a':container_title, 'b':self.context.application_number})
277        return super(CustomApplicantDisplayFormPage, self).label
[11784]278
[11782]279    @property
280    def form_fields(self):
[16164]281        if self.target is not None and self.target == 'tscf':
[16131]282            form_fields = grok.AutoFields(ITranscriptApplicant)
283            for field in TRANS_OMIT_FIELDS:
284                form_fields = form_fields.omit(field)
[16078]285            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
[16151]286            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
[16078]287            return form_fields
[16164]288        if self.target is not None and self.target == 'tscs':
[16131]289            form_fields = grok.AutoFields(ITranscriptApplicant)
290            for field in TRANS_SHORT_OMIT_FIELDS:
291                form_fields = form_fields.omit(field)
292            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
[16151]293            #form_fields['perm_address'].custom_widget = BytesDisplayWidget
[16131]294            return form_fields
[16807]295        if self.target is not None and self.target == 'flc':
[16804]296            form_fields = grok.AutoFields(IFrenchApplicant)
297            for field in REGISTRATION_OMIT_DISPLAY_FIELDS:
298                form_fields = form_fields.omit(field)
299            return form_fields
[13796]300        if self.target == 'ictwk':
[13814]301            form_fields = grok.AutoFields(IUnibenRegistration)
302            for field in REGISTRATION_OMIT_DISPLAY_FIELDS:
[13796]303                form_fields = form_fields.omit(field)
304            return form_fields
[14105]305        elif self.target is not None and self.target.startswith('pg'):
306            form_fields = grok.AutoFields(ICustomPGApplicant)
307            for field in PG_OMIT_DISPLAY_FIELDS:
308                form_fields = form_fields.omit(field)
309        elif self.target is not None and self.target.startswith('pre'):
310            form_fields = grok.AutoFields(ICustomPGApplicant)
311            for field in PRE_OMIT_DISPLAY_FIELDS:
312                form_fields = form_fields.omit(field)
313        elif self.target is not None and self.target.startswith('cbt'):
314            form_fields = grok.AutoFields(ICustomUGApplicant)
315            for field in CBT_OMIT_DISPLAY_FIELDS:
316                form_fields = form_fields.omit(field)
317        elif self.target is not None and self.target.startswith('akj'):
318            form_fields = grok.AutoFields(ICustomPGApplicant)
319            for field in PRE_OMIT_DISPLAY_FIELDS:
320                form_fields = form_fields.omit(field)
321        elif self.target is not None and self.target.startswith('ak'):
322            form_fields = grok.AutoFields(ICustomUGApplicant)
323            for field in AFFIL_OMIT_DISPLAY_FIELDS:
324                form_fields = form_fields.omit(field)
325        elif self.target is not None and self.target.startswith('ase'): # was putme
326            form_fields = grok.AutoFields(ICustomUGApplicant)
327            for field in PUTME_OMIT_DISPLAY_FIELDS:
328                form_fields = form_fields.omit(field)
[17538]329        elif self.target is not None and self.target.startswith('pt'):
330            form_fields = grok.AutoFields(ICustomUGApplicant)
331            for field in PT_OMIT_DISPLAY_FIELDS:
332                form_fields = form_fields.omit(field)
[14105]333        elif self.target is not None and self.target.startswith('pude'):
334            form_fields = grok.AutoFields(ICustomUGApplicant)
335            for field in PUDE_OMIT_DISPLAY_FIELDS:
336                form_fields = form_fields.omit(field)
337        else:
338            form_fields = grok.AutoFields(ICustomUGApplicant)
339            for field in UG_OMIT_DISPLAY_FIELDS:
340                form_fields = form_fields.omit(field)
341        #form_fields['perm_address'].custom_widget = BytesDisplayWidget
[17538]342        try:
343            form_fields['notice'].custom_widget = BytesDisplayWidget
344        except:
345            pass
[14105]346        if not getattr(self.context, 'student_id'):
347            form_fields = form_fields.omit('student_id')
348        if not getattr(self.context, 'screening_score'):
349            form_fields = form_fields.omit('screening_score')
350        if not getattr(self.context, 'screening_venue') or self._not_paid():
351            form_fields = form_fields.omit('screening_venue')
352        if not getattr(self.context, 'screening_date') or self._not_paid():
353            form_fields = form_fields.omit('screening_date')
[11784]354        if not self.context.admchecking_fee_paid():
355            form_fields = form_fields.omit(
356                'screening_score', 'aggregate', 'student_id')
[11782]357        return form_fields
358
[11784]359    @property
360    def display_actions(self):
361        state = IWorkflowState(self.context).getState()
362        actions = []
363        if state == ADMITTED and not self.context.admchecking_fee_paid():
364            actions = [_('Add admission checking payment ticket')]
365        return actions
366
367
368    def getCourseAdmitted(self):
369        """Return link, title and code in html format to the certificate
370           admitted.
371        """
[15125]372        if self.admission_checking_info:
373            return '<span class="hint">%s</span>' % self.admission_checking_info
374        return super(CustomApplicantDisplayFormPage, self).getCourseAdmitted()
[11784]375
[11786]376    @property
377    def admission_checking_info(self):
378        if self.context.state == ADMITTED and \
379            not self.context.admchecking_fee_paid():
380            return _('You must pay the admission checking fee '
[15125]381                     'to view your screening results and your course admitted.')
[11786]382        return
383
[11784]384    @action(_('Add admission checking payment ticket'), style='primary')
385    def addPaymentTicket(self, **data):
386        self.redirect(self.url(self.context, '@@addacp'))
387        return
388
[11728]389class CustomApplicationFeePaymentAddPage(ApplicationFeePaymentAddPage):
390    """ Page to add an online payment ticket
391    """
[10378]392
[11728]393    @property
394    def custom_requirements(self):
[15506]395        if self.context.__parent__.with_picture:
396            store = getUtility(IExtFileStore)
[16211]397            if self.context.__parent__.picture_editable \
398                and not store.getFileByContext(self.context, attr=u'passport.jpg'):
[15506]399                return _('Upload your 1"x1" Red background passport photo before making payment.')
[11728]400        return ''
401
[11784]402class AdmissionCheckingFeePaymentAddPage(UtilityView, grok.View):
403    """ Page to add an admission checking online payment ticket.
404    """
405    grok.context(ICustomApplicant)
406    grok.name('addacp')
407    grok.require('waeup.payApplicant')
408    factory = u'waeup.ApplicantOnlinePayment'
409
410    def _setPaymentDetails(self, payment):
411        container = self.context.__parent__
412        timestamp = ("%d" % int(time()*10000))[1:]
413        session = str(container.year)
414        try:
415            session_config = grok.getSite()['configuration'][session]
416        except KeyError:
417            return _(u'Session configuration object is not available.'), None
418        payment.p_id = "p%s" % timestamp
419        payment.p_item = container.title
420        payment.p_session = container.year
421        payment.amount_auth = 0.0
422        payment.p_category = 'admission_checking'
423        payment.amount_auth = session_config.admchecking_fee
424        if payment.amount_auth in (0.0, None):
425            return _('Amount could not be determined.'), None
426        return
427
[11782]428    def update(self):
[11784]429        if self.context.admchecking_fee_paid():
430              self.flash(
431                  _('Admission checking payment has already been made.'),
432                  type='warning')
433              self.redirect(self.url(self.context))
434              return
[11782]435        payment = createObject(self.factory)
[11784]436        failure = self._setPaymentDetails(payment)
[11782]437        if failure is not None:
438            self.flash(failure[0], type='danger')
439            self.redirect(self.url(self.context))
440            return
441        self.context[payment.p_id] = payment
442        self.flash(_('Payment ticket created.'))
443        self.redirect(self.url(payment))
444        return
[11736]445
[11784]446    def render(self):
447        return
[11736]448
[11784]449
[11782]450class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
451
[11736]452    @property
[13887]453    def display_payments(self):
454        if self.context.special or self.target == 'ictwk':
455            return True
456        return getattr(self.context.__parent__, 'application_fee', None)
457
458    @property
[11736]459    def custom_upload_requirements(self):
460        if not checkPermission('waeup.uploadPassportPictures', self.context):
461            return _('You are not entitled to upload passport pictures.')
[11782]462
[16683]463    def display_fileupload(self, filename):
464        if filename[1] == 'res_stat' \
465            and self.target is not None \
466            and not self.target.startswith('tsc'):
467            return False
468        if filename[1] == 'eligibility' \
469            and self.target is not None \
470            and not self.target.startswith('tsc'):
471            return False
472        return True
473
[13796]474    @property
[13814]475    def label(self):
476        if self.target == 'ictwk':
477            container_title = self.context.__parent__.title
478            return _('${a} <br /> Registration Record ${b}', mapping = {
479                'a':container_title, 'b':self.context.application_number})
480        return super(CustomApplicantManageFormPage, self).label
481
482    @property
[13796]483    def form_fields(self):
[16164]484        if self.target is not None and self.target == 'tscf':
[16078]485            form_fields = grok.AutoFields(ITranscriptApplicant)
[16227]486            for field in TRANS_OMIT_EDIT_FIELDS:
[16131]487                form_fields = form_fields.omit(field)
[16078]488            return form_fields
[16164]489        if self.target is not None and self.target == 'tscs':
[16131]490            form_fields = grok.AutoFields(ITranscriptApplicant)
[16227]491            for field in TRANS_SHORT_OMIT_EDIT_FIELDS:
[16131]492                form_fields = form_fields.omit(field)
493            return form_fields
[13796]494        if self.target == 'ictwk':
[13814]495            form_fields = grok.AutoFields(IUnibenRegistration)
496            for field in REGISTRATION_OMIT_MANAGE_FIELDS:
[13796]497                form_fields = form_fields.omit(field)
[13825]498            state = IWorkflowState(self.context).getState()
499            if state != STARTED:
500                form_fields['registration_cats'].for_display = True
[13814]501            return form_fields
[16807]502        if self.target is not None and self.target == 'flc':
[16804]503            form_fields = grok.AutoFields(IFrenchApplicant)
504            for field in REGISTRATION_OMIT_MANAGE_FIELDS:
505                form_fields = form_fields.omit(field)
506            return form_fields
[14105]507        if self.target is not None and self.target.startswith('pg'):
508            form_fields = grok.AutoFields(ICustomPGApplicant)
509            for field in PG_OMIT_MANAGE_FIELDS:
510                form_fields = form_fields.omit(field)
511        elif self.target is not None and self.target.startswith('pre'):
512            form_fields = grok.AutoFields(ICustomPGApplicant)
513            for field in PRE_OMIT_MANAGE_FIELDS:
514                form_fields = form_fields.omit(field)
515        elif self.target is not None and self.target.startswith('cbt'):
516            form_fields = grok.AutoFields(ICustomUGApplicant)
517            for field in CBT_OMIT_MANAGE_FIELDS:
518                form_fields = form_fields.omit(field)
519        elif self.target is not None and self.target.startswith('akj'):
520            form_fields = grok.AutoFields(ICustomPGApplicant)
521            for field in PRE_OMIT_MANAGE_FIELDS:
522                form_fields = form_fields.omit(field)
523        elif self.target is not None and self.target.startswith('ak'):
524            form_fields = grok.AutoFields(ICustomUGApplicant)
525            for field in AFFIL_OMIT_MANAGE_FIELDS:
526                form_fields = form_fields.omit(field)
527        elif self.target is not None and self.target.startswith('ase'): # was putme
528            form_fields = grok.AutoFields(ICustomUGApplicant)
529            for field in PUTME_OMIT_MANAGE_FIELDS:
530                form_fields = form_fields.omit(field)
[17538]531        elif self.target is not None and self.target.startswith('pt'):
532            form_fields = grok.AutoFields(ICustomUGApplicant)
533            for field in PT_OMIT_MANAGE_FIELDS:
534                form_fields = form_fields.omit(field)
[14105]535        elif self.target is not None and self.target.startswith('pude'):
536            form_fields = grok.AutoFields(ICustomUGApplicant)
537            for field in PUDE_OMIT_MANAGE_FIELDS:
538                form_fields = form_fields.omit(field)
539        else:
540            form_fields = grok.AutoFields(ICustomUGApplicant)
541            for field in UG_OMIT_MANAGE_FIELDS:
542                form_fields = form_fields.omit(field)
[17538]543        try:
544            form_fields['student_id'].for_display = True
545        except:
546            pass
547        try:
548            form_fields['applicant_id'].for_display = True
549        except:
550            pass
[13796]551        return form_fields
552
553
554class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
555    """An applicant-centered edit view for applicant data.
556    """
557
[14841]558    def unremovable(self, ticket):
559        return True
560
[13796]561    @property
[13887]562    def display_payments(self):
563        if self.context.special or self.target == 'ictwk':
564            return True
565        return getattr(self.context.__parent__, 'application_fee', None)
566
567    @property
[13796]568    def form_fields(self):
[16766]569        state = IWorkflowState(self.context).getState()
[16164]570        if self.target is not None and self.target == 'tscf':
[16131]571            form_fields = grok.AutoFields(ITranscriptApplicant)
[16471]572            form_fields['courier_tno'].for_display = True
573            form_fields['proc_date'].for_display = True
[16766]574            if state == PAID:
575                form_fields['order'].for_display = True
[16804]576            form_fields = form_fields.omit('locked')
[17597]577
578            form_fields['date_of_birth'].field.required = True
579            #form_fields['nationality'].field.required = True
580            form_fields['email'].field.required = True
581            form_fields['phone'].field.required = True
582            form_fields['dispatch_address'].field.required = True
583            form_fields['entry_mode'].field.required = True
584            form_fields['entry_session'].field.required = True
585            form_fields['end_session'].field.required = True
586            form_fields['course_studied'].field.required = True
587            form_fields['collected'].field.required = True
588            form_fields['order'].field.required = True
589            form_fields['charge'].field.required = True
590            form_fields['no_copies'].field.required = True
591
592            for field in TRANS_OMIT_EDIT_FIELDS:
593                form_fields = form_fields.omit(field)
[16078]594            return form_fields
[16164]595        if self.target is not None and self.target == 'tscs':
[16131]596            form_fields = grok.AutoFields(ITranscriptApplicant)
[16471]597            form_fields['courier_tno'].for_display = True
598            form_fields['proc_date'].for_display = True
[17597]599
600            form_fields['date_of_birth'].field.required = True
601            #form_fields['nationality'].field.required = True
602            form_fields['email'].field.required = True
603            form_fields['phone'].field.required = True
604            form_fields['dispatch_address'].field.required = True
605            form_fields['entry_mode'].field.required = True
606            form_fields['entry_session'].field.required = True
607            form_fields['end_session'].field.required = True
608            form_fields['course_studied'].field.required = True
609            form_fields['collected'].field.required = True
610            form_fields['order'].field.required = True
611            form_fields['charge'].field.required = True
612            form_fields['no_copies'].field.required = True
613
[16227]614            for field in TRANS_SHORT_OMIT_EDIT_FIELDS:
[16131]615                form_fields = form_fields.omit(field)
[16804]616            form_fields = form_fields.omit('locked')
[16766]617            if state == PAID:
618                form_fields['order'].for_display = True
[16131]619            return form_fields
[13796]620        if self.target == 'ictwk':
[13814]621            form_fields = grok.AutoFields(IUnibenRegistration)
622            for field in REGISTRATION_OMIT_EDIT_FIELDS:
[13796]623                form_fields = form_fields.omit(field)
[13825]624            if state != STARTED:
625                form_fields['registration_cats'].for_display = True
[13814]626            return form_fields
[16807]627        if self.target is not None and self.target == 'flc':
[16804]628            form_fields = grok.AutoFields(IFrenchApplicant)
629            for field in REGISTRATION_OMIT_EDIT_FIELDS:
630                form_fields = form_fields.omit(field)
631            return form_fields
[14105]632        if self.target is not None and self.target.startswith('pg'):
633            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
634            for field in PG_OMIT_EDIT_FIELDS:
635                form_fields = form_fields.omit(field)
636        elif self.target is not None and self.target.startswith('pre'):
637            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
638            for field in PRE_OMIT_EDIT_FIELDS:
639                form_fields = form_fields.omit(field)
640        elif self.target is not None and self.target.startswith('cbt'):
641            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
642            for field in CBT_OMIT_EDIT_FIELDS:
643                form_fields = form_fields.omit(field)
644        elif self.target is not None and self.target.startswith('akj'):
645            form_fields = grok.AutoFields(ICustomPGApplicant)
646            for field in PRE_OMIT_EDIT_FIELDS:
647                form_fields = form_fields.omit(field)
648        elif self.target is not None and self.target.startswith('ak'):
649            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
650            for field in AFFIL_OMIT_EDIT_FIELDS:
651                form_fields = form_fields.omit(field)
652        elif self.target is not None and self.target.startswith('ase'): # was putme
653            form_fields = grok.AutoFields(IPUTMEApplicantEdit)
654            for field in PUTME_OMIT_EDIT_FIELDS:
655                form_fields = form_fields.omit(field)
[17538]656        elif self.target is not None and self.target.startswith('pt'):
657            form_fields = grok.AutoFields(IPUTMEApplicantEdit)
658            for field in PT_OMIT_EDIT_FIELDS:
659                form_fields = form_fields.omit(field)
[14105]660        elif self.target is not None and self.target.startswith('pude'):
661            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
662            for field in PUDE_OMIT_EDIT_FIELDS:
663                form_fields = form_fields.omit(field)
664        else:
665            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
666            for field in UG_OMIT_EDIT_FIELDS:
667                form_fields = form_fields.omit(field)
668        form_fields['applicant_id'].for_display = True
669        form_fields['reg_number'].for_display = True
[13796]670        return form_fields
671
[13814]672    @property
673    def label(self):
674        if self.target == 'ictwk':
675            container_title = self.context.__parent__.title
676            return _('${a} <br /> Registration Record ${b}', mapping = {
677                'a':container_title, 'b':self.context.application_number})
678        return super(CustomApplicantEditFormPage, self).label
679
[16164]680    def display_fileupload(self, filename):
[16683]681        if filename[1] == 'res_stat' \
[16164]682            and self.target is not None \
[16332]683            and not self.target.startswith('tsc'):
[16164]684            return False
[16683]685        if filename[1] == 'eligibility' \
[16164]686            and self.target is not None \
687            and not self.target.startswith('tsc'):
688            return False
689        return True
690
691    def dataNotComplete(self, data):
692        store = getUtility(IExtFileStore)
[16199]693        if self.context.__parent__.with_picture \
694            and self.context.__parent__.picture_editable:
[16164]695            store = getUtility(IExtFileStore)
696            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
697                return _('No passport picture uploaded.')
698        if self.target is not None \
699            and self.target.startswith('tscf') \
700            and not store.getFileByContext(self.context, attr=u'res_stat.pdf'):
701            return _('No statement of result pdf file uploaded.')
[17084]702        if self.target is not None \
703            and self.target.startswith('tsc') \
704            and (not self.context.order or not self.context.charge):
705            return _('Please select Type of Order and Transcript Charge.')
[17532]706        if self.target is not None \
707            and self.target.startswith('pt') \
708            and not self.context.jamb_reg_number:
709            return _('Please enter your JAMB Registration Number.')
[16164]710        return False
711
[11782]712class CustomOnlinePaymentApprovePage(OnlinePaymentApprovePage):
713    """ Approval view
714    """
715
716    def update(self):
[11784]717        if self.context.p_category == 'admission_checking':
718            if self.context.p_state == 'paid':
719                flashtype = 'warning'
720                msg = _('This ticket has already been paid.')
721                log = None
722            else:
723                self.context.approve()
724                log = 'payment approved: %s' % self.context.p_id
725                msg = _('Payment approved')
726                flashtype = 'success'
727        else:
728            flashtype, msg, log = self.context.approveApplicantPayment()
[11782]729        if log is not None:
730            applicant = self.context.__parent__
731            # Add log message to applicants.log
732            applicant.writeLogMessage(self, log)
733            # Add log message to payments.log
734            self.context.logger.info(
735                '%s,%s,%s,%s,%s,,,,,,' % (
736                applicant.applicant_id,
737                self.context.p_id, self.context.p_category,
738                self.context.amount_auth, self.context.r_code))
739        self.flash(msg, type=flashtype)
740        return
[11784]741
742class CustomExportPDFPageApplicationSlip(ExportPDFPageApplicationSlip):
743    """Deliver a PDF slip of the context.
744    """
745
746    def update(self):
747        super(CustomExportPDFPageApplicationSlip, self).update()
748        if self.context.state == ADMITTED and \
749            not self.context.admchecking_fee_paid():
750            self.flash(
751                _('Please pay admission checking fee before trying to download '
752                  'the application slip.'), type='warning')
753            return self.redirect(self.url(self.context))
754        return
[13552]755
[13557]756class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
[13552]757
[13558]758    def _getPDFCreator(self):
[14061]759        if self.target.startswith('ak'):
[13558]760            return getUtility(IPDFCreator, name='akoka_pdfcreator')
761        return getUtility(IPDFCreator)
762
[13552]763    @property
[13814]764    def form_fields(self):
[16184]765        if self.target is not None and self.target == 'tscf':
766            form_fields = grok.AutoFields(ITranscriptApplicant)
[16227]767            for field in TRANS_OMIT_PDF_FIELDS:
[16184]768                form_fields = form_fields.omit(field)
769        elif self.target is not None and self.target == 'tscs':
770            form_fields = grok.AutoFields(ITranscriptApplicant)
[16227]771            for field in TRANS_SHORT_OMIT_PDF_FIELDS:
[16184]772                form_fields = form_fields.omit(field)
773        elif self.target is not None and self.target == 'ictwk':
[13814]774            form_fields = grok.AutoFields(IUnibenRegistration)
775            for field in REGISTRATION_OMIT_PDF_FIELDS:
776                form_fields = form_fields.omit(field)
[16184]777        elif self.target is not None and self.target.startswith('pg'):
[14105]778            form_fields = grok.AutoFields(ICustomPGApplicant)
779            for field in PG_OMIT_PDF_FIELDS:
780                form_fields = form_fields.omit(field)
781        elif self.target is not None and self.target.startswith('pre'):
782            form_fields = grok.AutoFields(ICustomPGApplicant)
783            for field in PRE_OMIT_PDF_FIELDS:
784                form_fields = form_fields.omit(field)
785        elif self.target is not None and self.target.startswith('cbt'): # uniben
786            form_fields = grok.AutoFields(ICustomUGApplicant)
787            for field in CBT_OMIT_PDF_FIELDS:
788                form_fields = form_fields.omit(field)
789        elif self.target is not None and self.target.startswith('akj'): # uniben
790            form_fields = grok.AutoFields(ICustomPGApplicant)
791            for field in PRE_OMIT_PDF_FIELDS:
792                form_fields = form_fields.omit(field)
793        elif self.target is not None and self.target.startswith('ak'): # uniben
794            form_fields = grok.AutoFields(ICustomUGApplicant)
795            for field in AFFIL_OMIT_PDF_FIELDS:
796                form_fields = form_fields.omit(field)
797        elif self.target is not None and self.target.startswith('ase'): # was putme
798            form_fields = grok.AutoFields(ICustomUGApplicant)
799            if self._reduced_slip():
800                for field in PUTME_OMIT_RESULT_SLIP_FIELDS:
801                    form_fields = form_fields.omit(field)
802            else:
803                for field in PUTME_OMIT_PDF_FIELDS:
804                    form_fields = form_fields.omit(field)
[17538]805        elif self.target is not None and self.target.startswith('pt'):
806            form_fields = grok.AutoFields(ICustomUGApplicant)
807            if self._reduced_slip():
808                for field in PT_OMIT_RESULT_SLIP_FIELDS:
809                    form_fields = form_fields.omit(field)
810            else:
811                for field in PT_OMIT_PDF_FIELDS:
812                    form_fields = form_fields.omit(field)
[14105]813        elif self.target is not None and self.target.startswith('pude'):
814            form_fields = grok.AutoFields(ICustomUGApplicant)
815            if self._reduced_slip():
816                for field in PUDE_OMIT_RESULT_SLIP_FIELDS:
817                    form_fields = form_fields.omit(field)
818            else:
819                for field in PUDE_OMIT_PDF_FIELDS:
820                    form_fields = form_fields.omit(field)
[16807]821        elif self.target is not None and self.target == 'flc':
[16804]822            form_fields = grok.AutoFields(IFrenchApplicant)
823            for field in REGISTRATION_OMIT_PDF_FIELDS:
824                form_fields = form_fields.omit(field)
[14105]825        else:
826            form_fields = grok.AutoFields(ICustomUGApplicant)
827            for field in UG_OMIT_PDF_FIELDS:
828                form_fields = form_fields.omit(field)
829        if not getattr(self.context, 'student_id'):
830            form_fields = form_fields.omit('student_id')
831        if not getattr(self.context, 'screening_score'):
832            form_fields = form_fields.omit('screening_score')
833        if not getattr(self.context, 'screening_venue'):
834            form_fields = form_fields.omit('screening_venue')
835        if not getattr(self.context, 'screening_date'):
836            form_fields = form_fields.omit('screening_date')
[13814]837        return form_fields
838
839    @property
[13552]840    def title(self):
841        container_title = self.context.__parent__.title
842        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
843        ar_translation = translate(_('Application Record'),
844            'waeup.kofa', target_language=portal_language)
[13814]845        if self.target == 'ictwk':
846            return '%s - Registration Record %s' % (container_title,
847            self.context.application_number)
[14061]848        elif self.target.startswith('ab'):
[13552]849            return 'Federal College of Education (Technical) Asaba - %s %s %s' % (
850                container_title, ar_translation,
851                self.context.application_number)
[14061]852        elif self.target.startswith('ak'):
[14064]853            return 'Federal College of Education (Technical) Akoka - %s - %s %s' % (
[13552]854                container_title, ar_translation,
855                self.context.application_number)
[13615]856        elif self.target == 'pgn':
857            return 'National Institute for Legislative Studies (NILS) - %s %s %s' % (
858                container_title, ar_translation,
859                self.context.application_number)
[13552]860        return '%s - %s %s' % (container_title,
861            ar_translation, self.context.application_number)
[14147]862
[16504]863class CustomApplicantBaseDisplayFormPage(ApplicantBaseDisplayFormPage):
864
865    @property
866    def form_fields(self):
867        target = getattr(self.context.__parent__, 'prefix', None)
868        if target.startswith('tsc'):
869            form_fields = grok.AutoFields(ICustomApplicant).select(
870                'applicant_id', 'email', 'dispatch_address')
871        else:
872            form_fields = grok.AutoFields(ICustomApplicant).select(
873                'applicant_id', 'reg_number', 'email', 'course1')
874        if self.context.__parent__.prefix in ('special',):
875            form_fields['reg_number'].field.title = u'Identification Number'
876            return form_fields
877        return form_fields
878
879class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):
880    """Deliver a PDF slip of the context.
881    """
882
883    @property
884    def omit_fields(self):
885        target = getattr(self.context.__parent__.__parent__, 'prefix', None)
886        if target.startswith('tsc'):
887            return ('date_of_birth', 'course1')
[16684]888        return ()
[16504]889
890    @property
891    def note(self):
892        return
893
894    def render(self):
895        if self.payment_slip_download_warning:
896            self.flash(self.payment_slip_download_warning, type='danger')
897            self.redirect(self.url(self.context))
898            return
899        applicantview = CustomApplicantBaseDisplayFormPage(self.context.__parent__,
900            self.request)
901        students_utils = getUtility(IStudentsUtils)
902        return students_utils.renderPDF(self,'payment_slip.pdf',
903            self.context.__parent__, applicantview,
904            note=self.note, omit_fields=self.omit_fields)
905
[14147]906class ExportScreeningInvitationSlip(UtilityView, grok.View):
907    """Deliver a PDF slip of the context.
908    """
909    grok.context(ICustomApplicant)
910    grok.name('screening_invitation_slip.pdf')
911    grok.require('waeup.viewApplication')
912    form_fields = None
[14148]913    label = u'Invitation Letter for Pre-Admission Screening'
[14147]914
915
916    @property
917    def note(self):
[16345]918        notice = getattr(self.context.__parent__, 'application_slip_notice')
[16346]919        if notice is None:
[16347]920            notice = ''
[14147]921        if self.context.screening_date:
922            return """
923<br /><br /><br /><br /><font size='12'>
924Dear %s,
925<br /><br /><br />
926You are invited for your Uniben Admission Screening Exercise on:
927<br /><br />
928<strong>%s</strong>.
929<br /><br />
[14167]930Please bring along this letter of invitation to the
[14147]931<br /><br />
[14167]932<strong>%s</strong>
933<br /><br />
[14147]934on your screening date.
935<br /><br /><br />
936Signed,
937<br /><br />
938The Registrar<br />
[14168]939<br /><br />
940<br /><br />
941%s
[14147]942</font>
943
[14167]944""" % (self.context.display_fullname, self.context.screening_date,
[14168]945       self.context.screening_venue, notice)
[14147]946        return
947
948    def update(self):
949        if not self.context.screening_date:
950            self.flash(_('Forbidden'), type="warning")
951            self.redirect(self.url(self.context))
952
953    def render(self):
954        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
955        students_utils = getUtility(IStudentsUtils)
956        return students_utils.renderPDF(self,'screening_invitation_slip.pdf',
[16117]957            self.context, applicantview, note=self.note)
958
959class CustomCheckTranscriptStatus(CheckTranscriptStatus):
960    """A display page for checking transcript processing status.
961    """
[16759]962    grok.template('checktranscriptstatus')
963
[16588]964    websites = (('Uniben Alumni Portal', 'https://alumni.uniben.edu/'),
[16582]965                ('Uniben Student Portal', 'https://waeup.uniben.edu/'),)
[16588]966    appl_url1 = 'https://alumni.uniben.edu/applicants/tscf1/register'
967    appl_url2 = 'https://alumni.uniben.edu/applicants/tscs1/register'
[16164]968
[16229]969class CreateGraduatedPage(UtilityView, grok.View):
970    """Create a student object from transcript application data.
971    """
972    grok.context(ICustomApplicant)
973    grok.name('creategraduated')
974    grok.require('waeup.createStudents')
975
976    def update(self):
977        success, msg = self.context.createStudent(view=self, graduated=True)
978        if success:
979            self.flash(msg)
980        else:
981            self.flash(msg, type='warning')
982        self.redirect(self.url(self.context))
983        return
984
985    def render(self):
986        return
987
[16164]988class ResultStatement(AdditionalFile):
[16547]989    grok.name('res_stat')
[16164]990
991class EligibilityForm(AdditionalFile):
[16547]992    grok.name('eligibility')
Note: See TracBrowser for help on using the repository browser.