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

Last change on this file since 11784 was 11784, checked in by Henrik Bettermann, 10 years ago

Implement admission checking fee payment. Completely untested! Tests will follow.

  • Property svn:keywords set to Id
File size: 10.3 KB
Line 
1## $Id: browser.py 11784 2014-08-29 19:04: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 hurry.workflow.interfaces import IWorkflowState
25from waeup.kofa.browser.layout import action, UtilityView
26from waeup.kofa.interfaces import IExtFileStore
27from waeup.kofa.applicants.browser import (
28    ApplicantRegistrationPage, ApplicantsContainerPage,
29    ApplicationFeePaymentAddPage,
30    OnlinePaymentApprovePage,
31    ExportPDFPageApplicationSlip)
32from waeup.kofa.applicants.interfaces import (
33    ISpecialApplicant, IApplicantsUtils)
34from kofacustom.nigeria.applicants.browser import (
35    NigeriaApplicantDisplayFormPage,
36    NigeriaApplicantManageFormPage,
37    NigeriaPDFApplicationSlip)
38from waeup.uniben.applicants.interfaces import (
39    ICustomApplicant)
40from waeup.kofa.applicants.workflow import ADMITTED, PAID
41
42from waeup.uniben.interfaces import MessageFactory as _
43
44PASTQ_ALL = ['ADT','EPCS','ESM','HEK','VTE']
45
46PASTQ_AL = ['ENL','FAA','FOL','HIS','LAL',
47            'PHL','THR','BUL','JIL','LAW','PPL','PUL'] + PASTQ_ALL
48
49PASTQ_BS = ['ANT','ANY','CHH','COH','HAE','MED','MEH','PHS','SUR',
50            'PCG','PCH','PCO', 'PCT','PHA','PHM','PMB','ANA','MBC',
51            'MLS','NSC','PSY','DPV','ODR','OSP','PER', 'RES','AEB',
52            'BCH','BOT','CED','EVL','MCB','OPT','PBB','SLT','ZOO',
53            'AEE','ANS', 'CRS','FIS','FOW','SOS'] + PASTQ_ALL
54
55PASTQ_EPS = ['CHE','CVE','DMIC','EEE','MCH','PEE','PRE','CHM',
56             'CSC','GLY','MTH','PHY'] + PASTQ_ALL
57
58PASTQ_MSS = ['ACC','BNK','BUS','ECO','GEO','POL','SAA','SWK'] + PASTQ_ALL
59
60class CustomApplicantsContainerPage(ApplicantsContainerPage):
61    """The standard view for regular applicant containers.
62    """
63
64    @property
65    def form_fields(self):
66        form_fields = super(CustomApplicantsContainerPage, self).form_fields
67        usertype = getattr(self.request.principal, 'user_type', None)
68        if self.request.principal.id == 'zope.anybody' or  \
69            usertype in ('applicant', 'student'):
70            return form_fields.omit('application_fee')
71        return form_fields
72
73class CustomApplicantRegistrationPage(ApplicantRegistrationPage):
74    """Captcha'd registration page for applicants.
75    """
76
77    def _redirect(self, email, password, applicant_id):
78        # Forward email and credentials to landing page.
79        self.redirect(self.url(self.context, 'registration_complete',
80            data = dict(email=email, password=password,
81            applicant_id=applicant_id)))
82        return
83
84class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
85    """A display view for applicant data.
86    """
87    grok.template('applicantdisplaypage')
88
89    def _show_pastq_putme(self):
90        return self.target.startswith('putme') \
91               and self.context.state in ('paid', 'submitted') \
92               and getattr(self.context, 'course1') is not None
93
94    @property
95    def show_pastq_al(self):
96        return self._show_pastq_putme() \
97               and self.context.course1.__parent__.__parent__.code in PASTQ_AL
98
99    @property
100    def show_pastq_bs(self):
101        return self._show_pastq_putme() \
102               and self.context.course1.__parent__.__parent__.code in PASTQ_BS
103
104    @property
105    def show_pastq_eps(self):
106        return self._show_pastq_putme() \
107               and self.context.course1.__parent__.__parent__.code in PASTQ_EPS
108
109    @property
110    def show_pastq_mss(self):
111        return self._show_pastq_putme() \
112               and self.context.course1.__parent__.__parent__.code in PASTQ_MSS
113
114    @property
115    def show_pastq_pude(self):
116        return self.target.startswith('pude') \
117               and self.context.state in ('paid', 'submitted')
118
119    # Customizations for admission checking payments
120
121    @property
122    def form_fields(self):
123        form_fields = super(CustomApplicantDisplayFormPage, self).form_fields
124        if not self.context.admchecking_fee_paid():
125            form_fields = form_fields.omit(
126                'screening_score', 'aggregate', 'student_id')
127        return form_fields
128
129    @property
130    def display_actions(self):
131        state = IWorkflowState(self.context).getState()
132        actions = []
133        if state == ADMITTED and not self.context.admchecking_fee_paid():
134            actions = [_('Add admission checking payment ticket')]
135        return actions
136
137
138    def getCourseAdmitted(self):
139        """Return link, title and code in html format to the certificate
140           admitted.
141        """
142        course_admitted = self.context.course_admitted
143        if getattr(course_admitted, '__parent__',None) and \
144            self.context.admchecking_fee_paid():
145            url = self.url(course_admitted)
146            title = course_admitted.title
147            code = course_admitted.code
148            return '<a href="%s">%s - %s</a>' %(url,code,title)
149        return ''
150
151    @action(_('Add admission checking payment ticket'), style='primary')
152    def addPaymentTicket(self, **data):
153        self.redirect(self.url(self.context, '@@addacp'))
154        return
155
156class CustomNigeriaPDFApplicationSlip(NigeriaPDFApplicationSlip):
157
158    @property
159    def note(self):
160        if self.target is not None and not self.target.startswith('pg') \
161            and not self._reduced_slip():
162            return _(u'<br /><br /><br />'
163                      'Comfirm your screening venue 72 hours to the screening. '
164                      '<br /><br />'
165                      'No bags, phones and calculators are allowed in the '
166                      'screening venues.')
167        return
168
169class CustomApplicationFeePaymentAddPage(ApplicationFeePaymentAddPage):
170    """ Page to add an online payment ticket
171    """
172
173    @property
174    def custom_requirements(self):
175        store = getUtility(IExtFileStore)
176        if not store.getFileByContext(self.context, attr=u'passport.jpg'):
177            return _('Upload your 1"x1" Red background passport photo before making payment.')
178        return ''
179
180class AdmissionCheckingFeePaymentAddPage(UtilityView, grok.View):
181    """ Page to add an admission checking online payment ticket.
182    """
183    grok.context(ICustomApplicant)
184    grok.name('addacp')
185    grok.require('waeup.payApplicant')
186    factory = u'waeup.ApplicantOnlinePayment'
187
188    def _setPaymentDetails(self, payment):
189        container = self.context.__parent__
190        timestamp = ("%d" % int(time()*10000))[1:]
191        session = str(container.year)
192        try:
193            session_config = grok.getSite()['configuration'][session]
194        except KeyError:
195            return _(u'Session configuration object is not available.'), None
196        payment.p_id = "p%s" % timestamp
197        payment.p_item = container.title
198        payment.p_session = container.year
199        payment.amount_auth = 0.0
200        payment.p_category = 'admission_checking'
201        payment.amount_auth = session_config.admchecking_fee
202        if payment.amount_auth in (0.0, None):
203            return _('Amount could not be determined.'), None
204        return
205
206    def update(self):
207        if self.context.admchecking_fee_paid():
208              self.flash(
209                  _('Admission checking payment has already been made.'),
210                  type='warning')
211              self.redirect(self.url(self.context))
212              return
213        payment = createObject(self.factory)
214        failure = self._setPaymentDetails(payment)
215        if failure is not None:
216            self.flash(failure[0], type='danger')
217            self.redirect(self.url(self.context))
218            return
219        self.context[payment.p_id] = payment
220        self.flash(_('Payment ticket created.'))
221        self.redirect(self.url(payment))
222        return
223
224    def render(self):
225        return
226
227
228class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
229
230    @property
231    def custom_upload_requirements(self):
232        if not checkPermission('waeup.uploadPassportPictures', self.context):
233            return _('You are not entitled to upload passport pictures.')
234
235class CustomOnlinePaymentApprovePage(OnlinePaymentApprovePage):
236    """ Approval view
237    """
238
239
240    def update(self):
241        if self.context.p_category == 'admission_checking':
242            if self.context.p_state == 'paid':
243                flashtype = 'warning'
244                msg = _('This ticket has already been paid.')
245                log = None
246            else:
247                self.context.approve()
248                log = 'payment approved: %s' % self.context.p_id
249                msg = _('Payment approved')
250                flashtype = 'success'
251        else:
252            flashtype, msg, log = self.context.approveApplicantPayment()
253        if log is not None:
254            applicant = self.context.__parent__
255            # Add log message to applicants.log
256            applicant.writeLogMessage(self, log)
257            # Add log message to payments.log
258            self.context.logger.info(
259                '%s,%s,%s,%s,%s,,,,,,' % (
260                applicant.applicant_id,
261                self.context.p_id, self.context.p_category,
262                self.context.amount_auth, self.context.r_code))
263        self.flash(msg, type=flashtype)
264        return
265
266class CustomExportPDFPageApplicationSlip(ExportPDFPageApplicationSlip):
267    """Deliver a PDF slip of the context.
268    """
269
270
271    def update(self):
272        super(CustomExportPDFPageApplicationSlip, self).update()
273        if self.context.state == ADMITTED and \
274            not self.context.admchecking_fee_paid():
275            self.flash(
276                _('Please pay admission checking fee before trying to download '
277                  'the application slip.'), type='warning')
278            return self.redirect(self.url(self.context))
279        return
Note: See TracBrowser for help on using the repository browser.