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

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

Changing registration_cats is only allowed before having made payment.

  • Property svn:keywords set to Id
File size: 14.7 KB
Line 
1## $Id: browser.py 13825 2016-04-11 05:59:02Z 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    def _show_pastq_putme(self):
113        return self.target.startswith('putme') \
114               and self.context.state in ('paid', 'submitted') \
115               and getattr(self.context, 'course1') is not None
116
117    @property
118    def show_pastq_al(self):
119        return self._show_pastq_putme() \
120               and self.context.course1.__parent__.__parent__.code in PASTQ_AL
121
122    @property
123    def show_pastq_bs(self):
124        return self._show_pastq_putme() \
125               and self.context.course1.__parent__.__parent__.code in PASTQ_BS
126
127    @property
128    def show_pastq_eps(self):
129        return self._show_pastq_putme() \
130               and self.context.course1.__parent__.__parent__.code in PASTQ_EPS
131
132    @property
133    def show_pastq_mss(self):
134        return self._show_pastq_putme() \
135               and self.context.course1.__parent__.__parent__.code in PASTQ_MSS
136
137    @property
138    def show_pastq_pude(self):
139        return self.target.startswith('pude') \
140               and self.context.state in ('paid', 'submitted')
141
142    @property
143    def label(self):
144        if self.target == 'ictwk':
145            container_title = self.context.__parent__.title
146            return _('${a} <br /> Registration Record ${b}', mapping = {
147                'a':container_title, 'b':self.context.application_number})
148        return super(CustomApplicantDisplayFormPage, self).label
149
150    @property
151    def form_fields(self):
152        if self.target == 'ictwk':
153            form_fields = grok.AutoFields(IUnibenRegistration)
154            for field in REGISTRATION_OMIT_DISPLAY_FIELDS:
155                form_fields = form_fields.omit(field)
156            return form_fields
157        form_fields = super(CustomApplicantDisplayFormPage, self).form_fields
158        if not self.context.admchecking_fee_paid():
159            form_fields = form_fields.omit(
160                'screening_score', 'aggregate', 'student_id')
161        return form_fields
162
163    @property
164    def display_actions(self):
165        state = IWorkflowState(self.context).getState()
166        actions = []
167        if state == ADMITTED and not self.context.admchecking_fee_paid():
168            actions = [_('Add admission checking payment ticket')]
169        return actions
170
171
172    def getCourseAdmitted(self):
173        """Return link, title and code in html format to the certificate
174           admitted.
175        """
176        course_admitted = self.context.course_admitted
177        if getattr(course_admitted, '__parent__',None) and \
178            self.context.admchecking_fee_paid():
179            url = self.url(course_admitted)
180            title = course_admitted.title
181            code = course_admitted.code
182            return '<a href="%s">%s - %s</a>' %(url,code,title)
183        return ''
184
185    @property
186    def admission_checking_info(self):
187        if self.context.state == ADMITTED and \
188            not self.context.admchecking_fee_paid():
189            return _('You must pay the admission checking fee '
190                     'to view your screening results and course admitted.')
191        return
192
193    @action(_('Add admission checking payment ticket'), style='primary')
194    def addPaymentTicket(self, **data):
195        self.redirect(self.url(self.context, '@@addacp'))
196        return
197
198class CustomApplicationFeePaymentAddPage(ApplicationFeePaymentAddPage):
199    """ Page to add an online payment ticket
200    """
201
202    @property
203    def custom_requirements(self):
204        store = getUtility(IExtFileStore)
205        if not store.getFileByContext(self.context, attr=u'passport.jpg'):
206            return _('Upload your 1"x1" Red background passport photo before making payment.')
207        return ''
208
209class AdmissionCheckingFeePaymentAddPage(UtilityView, grok.View):
210    """ Page to add an admission checking online payment ticket.
211    """
212    grok.context(ICustomApplicant)
213    grok.name('addacp')
214    grok.require('waeup.payApplicant')
215    factory = u'waeup.ApplicantOnlinePayment'
216
217    def _setPaymentDetails(self, payment):
218        container = self.context.__parent__
219        timestamp = ("%d" % int(time()*10000))[1:]
220        session = str(container.year)
221        try:
222            session_config = grok.getSite()['configuration'][session]
223        except KeyError:
224            return _(u'Session configuration object is not available.'), None
225        payment.p_id = "p%s" % timestamp
226        payment.p_item = container.title
227        payment.p_session = container.year
228        payment.amount_auth = 0.0
229        payment.p_category = 'admission_checking'
230        payment.amount_auth = session_config.admchecking_fee
231        if payment.amount_auth in (0.0, None):
232            return _('Amount could not be determined.'), None
233        return
234
235    def update(self):
236        if self.context.admchecking_fee_paid():
237              self.flash(
238                  _('Admission checking payment has already been made.'),
239                  type='warning')
240              self.redirect(self.url(self.context))
241              return
242        payment = createObject(self.factory)
243        failure = self._setPaymentDetails(payment)
244        if failure is not None:
245            self.flash(failure[0], type='danger')
246            self.redirect(self.url(self.context))
247            return
248        self.context[payment.p_id] = payment
249        self.flash(_('Payment ticket created.'))
250        self.redirect(self.url(payment))
251        return
252
253    def render(self):
254        return
255
256
257class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
258
259    @property
260    def custom_upload_requirements(self):
261        if not checkPermission('waeup.uploadPassportPictures', self.context):
262            return _('You are not entitled to upload passport pictures.')
263
264    @property
265    def label(self):
266        if self.target == 'ictwk':
267            container_title = self.context.__parent__.title
268            return _('${a} <br /> Registration Record ${b}', mapping = {
269                'a':container_title, 'b':self.context.application_number})
270        return super(CustomApplicantManageFormPage, self).label
271
272    @property
273    def form_fields(self):
274        if self.target == 'ictwk':
275            form_fields = grok.AutoFields(IUnibenRegistration)
276            for field in REGISTRATION_OMIT_MANAGE_FIELDS:
277                form_fields = form_fields.omit(field)
278            state = IWorkflowState(self.context).getState()
279            if state != STARTED:
280                form_fields['registration_cats'].for_display = True
281            return form_fields
282        form_fields = super(CustomApplicantManageFormPage, self).form_fields
283        return form_fields
284
285
286class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
287    """An applicant-centered edit view for applicant data.
288    """
289
290    @property
291    def form_fields(self):
292        if self.target == 'ictwk':
293            form_fields = grok.AutoFields(IUnibenRegistration)
294            for field in REGISTRATION_OMIT_EDIT_FIELDS:
295                form_fields = form_fields.omit(field)
296            state = IWorkflowState(self.context).getState()
297            if state != STARTED:
298                form_fields['registration_cats'].for_display = True
299            return form_fields
300        form_fields = super(CustomApplicantEditFormPage, self).form_fields
301        return form_fields
302
303    @property
304    def label(self):
305        if self.target == 'ictwk':
306            container_title = self.context.__parent__.title
307            return _('${a} <br /> Registration Record ${b}', mapping = {
308                'a':container_title, 'b':self.context.application_number})
309        return super(CustomApplicantEditFormPage, self).label
310
311class CustomOnlinePaymentApprovePage(OnlinePaymentApprovePage):
312    """ Approval view
313    """
314
315    def update(self):
316        if self.context.p_category == 'admission_checking':
317            if self.context.p_state == 'paid':
318                flashtype = 'warning'
319                msg = _('This ticket has already been paid.')
320                log = None
321            else:
322                self.context.approve()
323                log = 'payment approved: %s' % self.context.p_id
324                msg = _('Payment approved')
325                flashtype = 'success'
326        else:
327            flashtype, msg, log = self.context.approveApplicantPayment()
328        if log is not None:
329            applicant = self.context.__parent__
330            # Add log message to applicants.log
331            applicant.writeLogMessage(self, log)
332            # Add log message to payments.log
333            self.context.logger.info(
334                '%s,%s,%s,%s,%s,,,,,,' % (
335                applicant.applicant_id,
336                self.context.p_id, self.context.p_category,
337                self.context.amount_auth, self.context.r_code))
338        self.flash(msg, type=flashtype)
339        return
340
341class CustomExportPDFPageApplicationSlip(ExportPDFPageApplicationSlip):
342    """Deliver a PDF slip of the context.
343    """
344
345    def update(self):
346        super(CustomExportPDFPageApplicationSlip, self).update()
347        if self.context.state == ADMITTED and \
348            not self.context.admchecking_fee_paid():
349            self.flash(
350                _('Please pay admission checking fee before trying to download '
351                  'the application slip.'), type='warning')
352            return self.redirect(self.url(self.context))
353        return
354
355class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):
356
357    def _getPDFCreator(self):
358        if 'afak' in self.target:
359            return getUtility(IPDFCreator, name='akoka_pdfcreator')
360        return getUtility(IPDFCreator)
361
362    @property
363    def form_fields(self):
364        if self.target == 'ictwk':
365            form_fields = grok.AutoFields(IUnibenRegistration)
366            for field in REGISTRATION_OMIT_PDF_FIELDS:
367                form_fields = form_fields.omit(field)
368            return form_fields
369        form_fields = super(CustomPDFApplicationSlip, self).form_fields
370        return form_fields
371
372    @property
373    def title(self):
374        container_title = self.context.__parent__.title
375        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
376        ar_translation = translate(_('Application Record'),
377            'waeup.kofa', target_language=portal_language)
378        if self.target == 'ictwk':
379            return '%s - Registration Record %s' % (container_title,
380            self.context.application_number)
381        elif 'afas' in self.target:
382            return 'Federal College of Education (Technical) Asaba - %s %s %s' % (
383                container_title, ar_translation,
384                self.context.application_number)
385        elif 'afak' in self.target:
386            return 'Federal College of Education (Technical) Akoka - %s %s %s' % (
387                container_title, ar_translation,
388                self.context.application_number)
389        elif self.target == 'pgn':
390            return 'National Institute for Legislative Studies (NILS) - %s %s %s' % (
391                container_title, ar_translation,
392                self.context.application_number)
393        return '%s - %s %s' % (container_title,
394            ar_translation, self.context.application_number)
Note: See TracBrowser for help on using the repository browser.