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

Last change on this file since 13948 was 13947, checked in by Henrik Bettermann, 8 years ago

PUTME is obsolete. Rename putme to ase (Admission Screening Exercise). Use new links for past question pdf files.

  • Property svn:keywords set to Id
File size: 15.3 KB
Line 
1## $Id: browser.py 13947 2016-06-15 14:45:38Z 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
21from time import time
22from zope.component import getUtility, createObject
23from zope.security import checkPermission
24from zope.i18n import translate
25from hurry.workflow.interfaces import IWorkflowState
26from waeup.kofa.browser.layout import action, UtilityView
27from waeup.kofa.interfaces import IExtFileStore, IKofaUtils
28from waeup.kofa.applicants.browser import (
29    ApplicantRegistrationPage, ApplicantsContainerPage,
30    ApplicationFeePaymentAddPage,
31    OnlinePaymentApprovePage,
32    ExportPDFPageApplicationSlip)
33from waeup.kofa.applicants.interfaces import (
34    ISpecialApplicant, IApplicantsUtils)
35from waeup.kofa.browser.interfaces import IPDFCreator
36from kofacustom.nigeria.applicants.browser import (
37    NigeriaApplicantDisplayFormPage,
38    NigeriaApplicantManageFormPage,
39    NigeriaApplicantEditFormPage,
40    NigeriaPDFApplicationSlip)
41from waeup.uniben.applicants.interfaces import (
42    ICustomApplicant, IUnibenRegistration)
43from waeup.kofa.applicants.workflow import ADMITTED, PAID, STARTED
44
45from waeup.uniben.interfaces import MessageFactory as _
46
47PASTQ_ALL = ['ADT','EPCS','ESM','HEK','VTE']
48
49PASTQ_AL = ['ENL','FAA','FOL','HIS','LAL',
50            'PHL','THR','BUL','JIL','LAW','PPL','PUL'] + PASTQ_ALL
51
52PASTQ_BS = ['ANT','ANY','CHH','COH','HAE','MED','MEH','PHS','SUR',
53            'PCG','PCH','PCO', 'PCT','PHA','PHM','PMB','ANA','MBC',
54            'MLS','NSC','PSY','DPV','ODR','OSP','PER', 'RES','AEB',
55            'BCH','BOT','CED','EVL','MCB','OPT','PBB','SLT','ZOO',
56            'AEE','ANS', 'CRS','FIS','FOW','SOS'] + PASTQ_ALL
57
58PASTQ_EPS = ['CHE','CVE','DMIC','EEE','MCH','PEE','PRE','CHM',
59             'CSC','GLY','MTH','PHY'] + PASTQ_ALL
60
61PASTQ_MSS = ['ACC','BNK','BUS','ECO','GEO','POL','SAA','SWK'] + PASTQ_ALL
62
63REGISTRATION_OMIT_DISPLAY_FIELDS = (
64    'locked',
65    'suspended',
66    )
67
68REGISTRATION_OMIT_EDIT_FIELDS = (
69    'locked',
70    'suspended',
71    'applicant_id',
72    )
73
74REGISTRATION_OMIT_MANAGE_FIELDS = (
75    'applicant_id',
76    )
77
78
79REGISTRATION_OMIT_PDF_FIELDS = (
80    'locked',
81    'suspended',
82    )
83class CustomApplicantsContainerPage(ApplicantsContainerPage):
84    """The standard view for regular applicant containers.
85    """
86
87    @property
88    def form_fields(self):
89        form_fields = super(CustomApplicantsContainerPage, self).form_fields
90        usertype = getattr(self.request.principal, 'user_type', None)
91        if self.request.principal.id == 'zope.anybody' or  \
92            usertype in ('applicant', 'student'):
93            return form_fields.omit('application_fee')
94        return form_fields
95
96class CustomApplicantRegistrationPage(ApplicantRegistrationPage):
97    """Captcha'd registration page for applicants.
98    """
99
100    def _redirect(self, email, password, applicant_id):
101        # Forward email and credentials to landing page.
102        self.redirect(self.url(self.context, 'registration_complete',
103            data = dict(email=email, password=password,
104            applicant_id=applicant_id)))
105        return
106
107class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
108    """A display view for applicant data.
109    """
110    grok.template('applicantdisplaypage')
111
112    @property
113    def display_payments(self):
114        if self.context.special or self.target == 'ictwk':
115            return True
116        return getattr(self.context.__parent__, 'application_fee', None)
117
118    def _show_pastq_putme(self):
119        return self.target.startswith('ase') \
120               and self.context.state in ('paid', 'submitted') \
121               and getattr(self.context, 'course1') is not None
122
123    @property
124    def show_pastq_al(self):
125        return self._show_pastq_putme() \
126               and self.context.course1.__parent__.__parent__.code in PASTQ_AL
127
128    @property
129    def show_pastq_bs(self):
130        return self._show_pastq_putme() \
131               and self.context.course1.__parent__.__parent__.code in PASTQ_BS
132
133    @property
134    def show_pastq_eps(self):
135        return self._show_pastq_putme() \
136               and self.context.course1.__parent__.__parent__.code in PASTQ_EPS
137
138    @property
139    def show_pastq_mss(self):
140        return self._show_pastq_putme() \
141               and self.context.course1.__parent__.__parent__.code in PASTQ_MSS
142
143    @property
144    def show_pastq_pude(self):
145        return self.target.startswith('pude') \
146               and self.context.state in ('paid', 'submitted')
147
148    @property
149    def label(self):
150        if self.target == 'ictwk':
151            container_title = self.context.__parent__.title
152            return _('${a} <br /> Registration Record ${b}', mapping = {
153                'a':container_title, 'b':self.context.application_number})
154        return super(CustomApplicantDisplayFormPage, self).label
155
156    @property
157    def form_fields(self):
158        if self.target == 'ictwk':
159            form_fields = grok.AutoFields(IUnibenRegistration)
160            for field in REGISTRATION_OMIT_DISPLAY_FIELDS:
161                form_fields = form_fields.omit(field)
162            return form_fields
163        form_fields = super(CustomApplicantDisplayFormPage, self).form_fields
164        if not self.context.admchecking_fee_paid():
165            form_fields = form_fields.omit(
166                'screening_score', 'aggregate', 'student_id')
167        return form_fields
168
169    @property
170    def display_actions(self):
171        state = IWorkflowState(self.context).getState()
172        actions = []
173        if state == ADMITTED and not self.context.admchecking_fee_paid():
174            actions = [_('Add admission checking payment ticket')]
175        return actions
176
177
178    def getCourseAdmitted(self):
179        """Return link, title and code in html format to the certificate
180           admitted.
181        """
182        course_admitted = self.context.course_admitted
183        if getattr(course_admitted, '__parent__',None) and \
184            self.context.admchecking_fee_paid():
185            url = self.url(course_admitted)
186            title = course_admitted.title
187            code = course_admitted.code
188            return '<a href="%s">%s - %s</a>' %(url,code,title)
189        return ''
190
191    @property
192    def admission_checking_info(self):
193        if self.context.state == ADMITTED and \
194            not self.context.admchecking_fee_paid():
195            return _('You must pay the admission checking fee '
196                     'to view your screening results and course admitted.')
197        return
198
199    @action(_('Add admission checking payment ticket'), style='primary')
200    def addPaymentTicket(self, **data):
201        self.redirect(self.url(self.context, '@@addacp'))
202        return
203
204class CustomApplicationFeePaymentAddPage(ApplicationFeePaymentAddPage):
205    """ Page to add an online payment ticket
206    """
207
208    @property
209    def custom_requirements(self):
210        store = getUtility(IExtFileStore)
211        if not store.getFileByContext(self.context, attr=u'passport.jpg'):
212            return _('Upload your 1"x1" Red background passport photo before making payment.')
213        return ''
214
215class AdmissionCheckingFeePaymentAddPage(UtilityView, grok.View):
216    """ Page to add an admission checking online payment ticket.
217    """
218    grok.context(ICustomApplicant)
219    grok.name('addacp')
220    grok.require('waeup.payApplicant')
221    factory = u'waeup.ApplicantOnlinePayment'
222
223    def _setPaymentDetails(self, payment):
224        container = self.context.__parent__
225        timestamp = ("%d" % int(time()*10000))[1:]
226        session = str(container.year)
227        try:
228            session_config = grok.getSite()['configuration'][session]
229        except KeyError:
230            return _(u'Session configuration object is not available.'), None
231        payment.p_id = "p%s" % timestamp
232        payment.p_item = container.title
233        payment.p_session = container.year
234        payment.amount_auth = 0.0
235        payment.p_category = 'admission_checking'
236        payment.amount_auth = session_config.admchecking_fee
237        if payment.amount_auth in (0.0, None):
238            return _('Amount could not be determined.'), None
239        return
240
241    def update(self):
242        if self.context.admchecking_fee_paid():
243              self.flash(
244                  _('Admission checking payment has already been made.'),
245                  type='warning')
246              self.redirect(self.url(self.context))
247              return
248        payment = createObject(self.factory)
249        failure = self._setPaymentDetails(payment)
250        if failure is not None:
251            self.flash(failure[0], type='danger')
252            self.redirect(self.url(self.context))
253            return
254        self.context[payment.p_id] = payment
255        self.flash(_('Payment ticket created.'))
256        self.redirect(self.url(payment))
257        return
258
259    def render(self):
260        return
261
262
263class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
264
265    @property
266    def display_payments(self):
267        if self.context.special or self.target == 'ictwk':
268            return True
269        return getattr(self.context.__parent__, 'application_fee', None)
270
271    @property
272    def custom_upload_requirements(self):
273        if not checkPermission('waeup.uploadPassportPictures', self.context):
274            return _('You are not entitled to upload passport pictures.')
275
276    @property
277    def label(self):
278        if self.target == 'ictwk':
279            container_title = self.context.__parent__.title
280            return _('${a} <br /> Registration Record ${b}', mapping = {
281                'a':container_title, 'b':self.context.application_number})
282        return super(CustomApplicantManageFormPage, self).label
283
284    @property
285    def form_fields(self):
286        if self.target == 'ictwk':
287            form_fields = grok.AutoFields(IUnibenRegistration)
288            for field in REGISTRATION_OMIT_MANAGE_FIELDS:
289                form_fields = form_fields.omit(field)
290            state = IWorkflowState(self.context).getState()
291            if state != STARTED:
292                form_fields['registration_cats'].for_display = True
293            return form_fields
294        form_fields = super(CustomApplicantManageFormPage, self).form_fields
295        return form_fields
296
297
298class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
299    """An applicant-centered edit view for applicant data.
300    """
301
302    @property
303    def display_payments(self):
304        if self.context.special or self.target == 'ictwk':
305            return True
306        return getattr(self.context.__parent__, 'application_fee', None)
307
308    @property
309    def form_fields(self):
310        if self.target == 'ictwk':
311            form_fields = grok.AutoFields(IUnibenRegistration)
312            for field in REGISTRATION_OMIT_EDIT_FIELDS:
313                form_fields = form_fields.omit(field)
314            state = IWorkflowState(self.context).getState()
315            if state != STARTED:
316                form_fields['registration_cats'].for_display = True
317            return form_fields
318        form_fields = super(CustomApplicantEditFormPage, self).form_fields
319        return form_fields
320
321    @property
322    def label(self):
323        if self.target == 'ictwk':
324            container_title = self.context.__parent__.title
325            return _('${a} <br /> Registration Record ${b}', mapping = {
326                'a':container_title, 'b':self.context.application_number})
327        return super(CustomApplicantEditFormPage, self).label
328
329class CustomOnlinePaymentApprovePage(OnlinePaymentApprovePage):
330    """ Approval view
331    """
332
333    def update(self):
334        if self.context.p_category == 'admission_checking':
335            if self.context.p_state == 'paid':
336                flashtype = 'warning'
337                msg = _('This ticket has already been paid.')
338                log = None
339            else:
340                self.context.approve()
341                log = 'payment approved: %s' % self.context.p_id
342                msg = _('Payment approved')
343                flashtype = 'success'
344        else:
345            flashtype, msg, log = self.context.approveApplicantPayment()
346        if log is not None:
347            applicant = self.context.__parent__
348            # Add log message to applicants.log
349            applicant.writeLogMessage(self, log)
350            # Add log message to payments.log
351            self.context.logger.info(
352                '%s,%s,%s,%s,%s,,,,,,' % (
353                applicant.applicant_id,
354                self.context.p_id, self.context.p_category,
355                self.context.amount_auth, self.context.r_code))
356        self.flash(msg, type=flashtype)
357        return
358
359class CustomExportPDFPageApplicationSlip(ExportPDFPageApplicationSlip):
360    """Deliver a PDF slip of the context.
361    """
362
363    def update(self):
364        super(CustomExportPDFPageApplicationSlip, self).update()
365        if self.context.state == ADMITTED and \
366            not self.context.admchecking_fee_paid():
367            self.flash(
368                _('Please pay admission checking fee before trying to download '
369                  'the application slip.'), type='warning')
370            return self.redirect(self.url(self.context))
371        return
372
373class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
374
375    def _getPDFCreator(self):
376        if 'afak' in self.target:
377            return getUtility(IPDFCreator, name='akoka_pdfcreator')
378        return getUtility(IPDFCreator)
379
380    @property
381    def form_fields(self):
382        if self.target == 'ictwk':
383            form_fields = grok.AutoFields(IUnibenRegistration)
384            for field in REGISTRATION_OMIT_PDF_FIELDS:
385                form_fields = form_fields.omit(field)
386            return form_fields
387        form_fields = super(CustomPDFApplicationSlip, self).form_fields
388        return form_fields
389
390    @property
391    def title(self):
392        container_title = self.context.__parent__.title
393        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
394        ar_translation = translate(_('Application Record'),
395            'waeup.kofa', target_language=portal_language)
396        if self.target == 'ictwk':
397            return '%s - Registration Record %s' % (container_title,
398            self.context.application_number)
399        elif 'afas' in self.target:
400            return 'Federal College of Education (Technical) Asaba - %s %s %s' % (
401                container_title, ar_translation,
402                self.context.application_number)
403        elif 'afak' in self.target:
404            return 'Federal College of Education (Technical) Akoka - %s %s %s' % (
405                container_title, ar_translation,
406                self.context.application_number)
407        elif self.target == 'pgn':
408            return 'National Institute for Legislative Studies (NILS) - %s %s %s' % (
409                container_title, ar_translation,
410                self.context.application_number)
411        return '%s - %s %s' % (container_title,
412            ar_translation, self.context.application_number)
Note: See TracBrowser for help on using the repository browser.