source: main/waeup.uniben/trunk/src/waeup/uniben/students/utils.py @ 16382

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

Implement medical history questionnaire.

  • Property svn:keywords set to Id
File size: 29.0 KB
Line 
1## $Id: utils.py 16382 2021-01-22 22:49:43Z 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##
18import grok
19from time import time
20from reportlab.platypus import Paragraph, Table
21from zope.component import createObject, getUtility
22from reportlab.lib.styles import getSampleStyleSheet
23from waeup.kofa.browser.pdf import ENTRY1_STYLE
24from waeup.kofa.interfaces import (IKofaUtils, ADMITTED, CLEARANCE,
25    CLEARED, RETURNING, PAID, REGISTERED, VALIDATED, GRADUATED)
26from waeup.kofa.utils.helpers import to_timezone
27from waeup.kofa.students.utils import (
28    trans, render_student_data, formatted_text, render_transcript_data,
29    SLIP_STYLE)
30from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
31from waeup.uniben.interfaces import MessageFactory as _
32
33class CustomStudentsUtils(NigeriaStudentsUtils):
34    """A collection of customized methods.
35
36    """
37
38    SEPARATORS_DICT = {
39        'form.fst_sit_fname': _(u'First Sitting Record'),
40        'form.scd_sit_fname': _(u'Second Sitting Record'),
41        'form.alr_fname': _(u'Advanced Level Record'),
42        'form.hq_type': _(u'Higher Education Record'),
43        'form.hq2_type': _(u'Second Higher Education Record'),
44        'form.nysc_year': _(u'NYSC Information'),
45        'form.employer': _(u'Employment History'),
46        'form.former_matric': _(u'Former Student'),
47        'form.fever': _(u'History of Symptoms'),
48        'form.asthma': _(u'Medical History'),
49        'form.lagos_abuja': _(u'Travel History'),
50        'form.company_suspected': _(u'History of Contact/Infection'),
51        }
52
53    def getReturningData(self, student):
54        """ This method defines what happens after school fee payment
55        of returning students depending on the student's senate verdict.
56        """
57        prev_level = student['studycourse'].current_level
58        cur_verdict = student['studycourse'].current_verdict
59        if cur_verdict == 'N' and prev_level == 100:
60            new_level = prev_level
61        elif cur_verdict in ('A','B','L','M','N','Z',):
62            # Successful student
63            new_level = divmod(int(prev_level),100)[0]*100 + 100
64        elif cur_verdict == 'C':
65            # Student on probation
66            new_level = int(prev_level) + 10
67        else:
68            # Student is somehow in an undefined state.
69            # Level has to be set manually.
70            new_level = prev_level
71        new_session = student['studycourse'].current_session + 1
72        return new_session, new_level
73
74
75    def checkAccommodationRequirements(self, student, acc_details):
76        if acc_details.get('expired', False):
77            startdate = acc_details.get('startdate')
78            enddate = acc_details.get('enddate')
79            if startdate and enddate:
80                tz = getUtility(IKofaUtils).tzinfo
81                startdate = to_timezone(
82                    startdate, tz).strftime("%d/%m/%Y %H:%M:%S")
83                enddate = to_timezone(
84                    enddate, tz).strftime("%d/%m/%Y %H:%M:%S")
85                return _("Outside booking period: ${a} - ${b}",
86                         mapping = {'a': startdate, 'b': enddate})
87            else:
88                return _("Outside booking period.")
89        if not student.is_postgrad and student.current_mode != 'ug_ft':
90            return _("Only undergraduate full-time students are eligible to book accommodation.")
91        bt = acc_details.get('bt')
92        if not bt:
93            return _("Your data are incomplete.")
94        if not student.state in acc_details['allowed_states']:
95            return _("You are in the wrong registration state.")
96        if student['studycourse'].current_session != acc_details[
97            'booking_session']:
98            return _('Your current session does not '
99                     'match accommodation session.')
100        stage = bt.split('_')[2]
101        if not student.is_postgrad and stage != 'fr' and not student[
102            'studycourse'].previous_verdict in (
103                'A', 'B', 'F', 'J', 'L', 'M', 'C', 'Z'):
104            return _("Your are not eligible to book accommodation.")
105        bsession = str(acc_details['booking_session'])
106        if bsession in student['accommodation'].keys() \
107            and not 'booking expired' in \
108            student['accommodation'][bsession].bed_coordinates:
109            return _('You already booked a bed space in '
110                     'current accommodation session.')
111        return
112
113    def getAccommodationDetails(self, student):
114        """Determine the accommodation data of a student.
115        """
116        d = {}
117        d['error'] = u''
118        hostels = grok.getSite()['hostels']
119        d['booking_session'] = hostels.accommodation_session
120        d['allowed_states'] = hostels.accommodation_states
121        d['startdate'] = hostels.startdate
122        d['enddate'] = hostels.enddate
123        d['expired'] = hostels.expired
124        # Determine bed type
125        studycourse = student['studycourse']
126        certificate = getattr(studycourse,'certificate',None)
127        entry_session = studycourse.entry_session
128        current_level = studycourse.current_level
129        if None in (entry_session, current_level, certificate):
130            return d
131        if student.sex == 'f':
132            sex = 'female'
133        else:
134            sex = 'male'
135        if student.is_postgrad:
136            bt = 'all'
137            special_handling = 'pg'
138        else:
139            end_level = certificate.end_level
140            if current_level == 10:
141                bt = 'pr'
142            elif entry_session == grok.getSite()['hostels'].accommodation_session:
143                bt = 'fr'
144            elif current_level >= end_level:
145                bt = 'fi'
146            else:
147                bt = 're'
148            special_handling = 'regular'
149            desired_hostel = student['accommodation'].desired_hostel
150            if student.faccode in ('MED', 'DEN') and (
151                not desired_hostel or desired_hostel.startswith('clinical')):
152                special_handling = 'clinical'
153            elif student.certcode in ('BARTMAS', 'BARTTHR', 'BARTFAA',
154                                      'BAEDFAA', 'BSCEDECHED', 'BAFAA'):
155                special_handling = 'ekenwan'
156        d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
157        return d
158
159    def _paymentMade(self, student, session):
160        if len(student['payments']):
161            for ticket in student['payments'].values():
162                if ticket.p_state == 'paid' and \
163                    ticket.p_category == 'schoolfee' and \
164                    ticket.p_session == session:
165                    return True
166        return False
167
168    def _isPaymentDisabled(self, p_session, category, student):
169        academic_session = self._getSessionConfiguration(p_session)
170        if category == 'schoolfee':
171            if 'sf_all' in academic_session.payment_disabled:
172                return True
173            if student.current_mode == 'found' and \
174                'sf_found' in academic_session.payment_disabled:
175                return True
176            if student.is_postgrad:
177                if 'sf_pg' in academic_session.payment_disabled:
178                    return True
179                return False
180            if student.current_mode.endswith('ft') and \
181                'sf_ft' in academic_session.payment_disabled:
182                return True
183            if student.current_mode.endswith('pt') and \
184                'sf_pt' in academic_session.payment_disabled:
185                return True
186            if student.current_mode.startswith('dp') and \
187                'sf_dp' in academic_session.payment_disabled:
188                return True
189            if student.current_mode.endswith('sw') and \
190                'sf_sw' in academic_session.payment_disabled:
191                return True
192        if category == 'hostel_maintenance' and \
193            'maint_all' in academic_session.payment_disabled:
194            return True
195        if category == 'clearance':
196            if 'cl_all' in academic_session.payment_disabled:
197                return True
198            if student.is_jupeb and \
199                'cl_jupeb' in academic_session.payment_disabled:
200                return True
201            if not student.is_jupeb and \
202                'cl_allexj' in academic_session.payment_disabled:
203                return True
204        return False
205
206    #def _hostelApplicationPaymentMade(self, student, session):
207    #    if len(student['payments']):
208    #        for ticket in student['payments'].values():
209    #            if ticket.p_state == 'paid' and \
210    #                ticket.p_category == 'hostel_application' and \
211    #                ticket.p_session == session:
212    #                return True
213    #    return False
214
215    def _pharmdInstallments(self, student):
216        installments = 0.0
217        if len(student['payments']):
218            for ticket in student['payments'].values():
219                if ticket.p_state == 'paid' and \
220                    ticket.p_category.startswith('pharmd') and \
221                    ticket.p_session == student.current_session:
222                    installments += ticket.amount_auth
223        return installments
224
225    def samePaymentMade(self, student, category, p_item, p_session):
226        if category in ('bed_allocation', 'transcript'):
227            return False
228        for key in student['payments'].keys():
229            ticket = student['payments'][key]
230            if ticket.p_state == 'paid' and\
231               ticket.p_category == category and \
232               ticket.p_item == p_item and \
233               ticket.p_session == p_session:
234                  return True
235        return False
236
237    def setPaymentDetails(self, category, student,
238            previous_session, previous_level, combi):
239        """Create Payment object and set the payment data of a student for
240        the payment category specified.
241
242        """
243        p_item = u''
244        amount = 0.0
245        if previous_session:
246            if previous_session < student['studycourse'].entry_session:
247                return _('The previous session must not fall below '
248                         'your entry session.'), None
249            if category == 'schoolfee':
250                # School fee is always paid for the following session
251                if previous_session > student['studycourse'].current_session:
252                    return _('This is not a previous session.'), None
253            else:
254                if previous_session > student['studycourse'].current_session - 1:
255                    return _('This is not a previous session.'), None
256            p_session = previous_session
257            p_level = previous_level
258            p_current = False
259        else:
260            p_session = student['studycourse'].current_session
261            p_level = student['studycourse'].current_level
262            p_current = True
263        academic_session = self._getSessionConfiguration(p_session)
264        if academic_session == None:
265            return _(u'Session configuration object is not available.'), None
266        # Determine fee.
267        if category == 'transfer':
268            amount = academic_session.transfer_fee
269        elif category == 'transcript':
270            amount = academic_session.transcript_fee
271        elif category == 'gown':
272            amount = academic_session.gown_fee
273        elif category == 'jupeb':
274            amount = academic_session.jupeb_fee
275        elif category == 'clinexam':
276            amount = academic_session.clinexam_fee
277        elif category.startswith('pharmd') \
278            and student.current_mode == 'special_ft':
279            amount = 80000.0
280        #elif category == 'develop' and student.is_postgrad:
281        #    amount = academic_session.development_fee
282        elif category == 'bed_allocation':
283            p_item = self.getAccommodationDetails(student)['bt']
284            desired_hostel = student['accommodation'].desired_hostel
285            if not desired_hostel:
286                return _(u'Select your favoured hostel first.'), None
287            if desired_hostel and desired_hostel != 'no':
288                p_item = u'%s (%s)' % (p_item, desired_hostel)
289            amount = academic_session.booking_fee
290            if student.is_postgrad:
291                amount += 500
292        elif category == 'hostel_maintenance':
293            amount = 0.0
294            bedticket = student['accommodation'].get(
295                str(student.current_session), None)
296            if bedticket is not None and bedticket.bed is not None:
297                p_item = bedticket.bed_coordinates
298                if bedticket.bed.__parent__.maint_fee > 0:
299                    amount = bedticket.bed.__parent__.maint_fee
300                else:
301                    # fallback
302                    amount = academic_session.maint_fee
303            else:
304                return _(u'No bed allocated.'), None
305        #elif category == 'hostel_application':
306        #    amount = 1000.0
307        #elif category.startswith('tempmaint'):
308        #    if not self._hostelApplicationPaymentMade(
309        #        student, student.current_session):
310        #        return _(
311        #            'You have not yet paid the hostel application fee.'), None
312        #    if category == 'tempmaint_1':
313        #        amount = 8150.0
314        #    elif category == 'tempmaint_2':
315        #        amount = 12650.0
316        #    elif category == 'tempmaint_3':
317        #        amount = 9650.0
318        elif category == 'clearance':
319            p_item = student.certcode
320            if p_item is None:
321                return _('Study course data are incomplete.'), None
322            if student.is_jupeb:
323                amount = 50000.0
324            elif student.faccode.startswith('FCETA'):
325                # ASABA and AKOKA
326                amount = 35000.0
327            elif student.faccode in ('BMS', 'MED', 'DEN'):
328            #elif p_item in ('BSCANA', 'BSCMBC', 'BMLS', 'BSCNUR', 'BSCPHS', 'BDS',
329            #    'MBBSMED', 'MBBSNDU', 'BSCPTY', 'BSCPST'):
330                amount = 80000.0
331            elif student.faccode == 'DCOEM':
332                return _('Acceptance fee payment not necessary.'), None
333            else:
334                amount = 60000.0
335        elif category == 'schoolfee':
336            try:
337                certificate = student['studycourse'].certificate
338                p_item = certificate.code
339            except (AttributeError, TypeError):
340                return _('Study course data are incomplete.'), None
341            if previous_session:
342                # Students can pay for previous sessions in all workflow states.
343                # Fresh students are excluded by the update method of the
344                # PreviousPaymentAddFormPage.
345                if previous_session == student['studycourse'].entry_session:
346                    if student.is_foreigner:
347                        amount = getattr(certificate, 'school_fee_3', 0.0)
348                    else:
349                        amount = getattr(certificate, 'school_fee_1', 0.0)
350                else:
351                    if student.is_foreigner:
352                        amount = getattr(certificate, 'school_fee_4', 0.0)
353                    else:
354                        amount = getattr(certificate, 'school_fee_2', 0.0)
355                        # Old returning students might get a discount.
356                        if student.entry_session < 2017 \
357                            and certificate.custom_float_1:
358                            amount -= certificate.custom_float_1
359            else:
360                if student.state == CLEARED:
361                    if student.is_foreigner:
362                        amount = getattr(certificate, 'school_fee_3', 0.0)
363                    else:
364                        amount = getattr(certificate, 'school_fee_1', 0.0)
365                elif student.state == PAID and student.is_postgrad:
366                    p_session += 1
367                    academic_session = self._getSessionConfiguration(p_session)
368                    if academic_session == None:
369                        return _(u'Session configuration object is not available.'), None
370
371                    # Students are only allowed to pay for the next session
372                    # if current session payment
373                    # has really been made, i.e. payment object exists.
374                    #if not self._paymentMade(
375                    #    student, student.current_session):
376                    #    return _('You have not yet paid your current/active' +
377                    #             ' session. Please use the previous session' +
378                    #             ' payment form first.'), None
379
380                    if student.is_foreigner:
381                        amount = getattr(certificate, 'school_fee_4', 0.0)
382                    else:
383                        amount = getattr(certificate, 'school_fee_2', 0.0)
384                elif student.state == RETURNING:
385                    # In case of returning school fee payment the payment session
386                    # and level contain the values of the session the student
387                    # has paid for.
388                    p_session, p_level = self.getReturningData(student)
389                    academic_session = self._getSessionConfiguration(p_session)
390                    if academic_session == None:
391                        return _(u'Session configuration object is not available.'), None
392
393                    # Students are only allowed to pay for the next session
394                    # if current session payment has really been made,
395                    # i.e. payment object exists and is paid.
396                    #if not self._paymentMade(
397                    #    student, student.current_session):
398                    #    return _('You have not yet paid your current/active' +
399                    #             ' session. Please use the previous session' +
400                    #             ' payment form first.'), None
401
402                    if student.is_foreigner:
403                        amount = getattr(certificate, 'school_fee_4', 0.0)
404                    else:
405                        amount = getattr(certificate, 'school_fee_2', 0.0)
406                        # Old returning students might get a discount.
407                        if student.entry_session < 2017 \
408                            and certificate.custom_float_1:
409                            amount -= certificate.custom_float_1
410                # PHARMD school fee amount is fixed and previously paid
411                # installments in current session are deducted.
412                if student.current_mode == 'special_ft' \
413                    and student.state in (RETURNING, CLEARED):
414                    if student.is_foreigner:
415                        amount = 260000.0 - self._pharmdInstallments(student)
416                    else:
417                        amount = 160000.0 - self._pharmdInstallments(student)
418            # Give 50% school fee discount to staff members.
419            if student.is_staff:
420                amount /= 2
421        if amount in (0.0, None):
422            return _('Amount could not be determined.'), None
423        # Add session specific penalty fee.
424        if category == 'schoolfee' and student.is_postgrad:
425            amount += academic_session.penalty_pg
426            amount += academic_session.development_fee
427        elif category == 'schoolfee' and student.current_mode == ('ug_ft'):
428            amount += academic_session.penalty_ug_ft
429        elif category == 'schoolfee' and student.current_mode == ('ug_pt'):
430            amount += academic_session.penalty_ug_pt
431        elif category == 'schoolfee' and student.current_mode == ('ug_sw'):
432            amount += academic_session.penalty_sw
433        elif category == 'schoolfee' and student.current_mode in (
434            'dp_ft', 'dp_pt'):
435            amount += academic_session.penalty_dp
436        if category.startswith('tempmaint'):
437            p_item = getUtility(IKofaUtils).PAYMENT_CATEGORIES[category]
438            p_item = unicode(p_item)
439            # Now we change the category because tempmaint payments
440            # will be obsolete when Uniben returns to Kofa bed allocation.
441            category = 'hostel_maintenance'
442        # Create ticket.
443        if self.samePaymentMade(student, category, p_item, p_session):
444            return _('This type of payment has already been made.'), None
445        if self._isPaymentDisabled(p_session, category, student):
446            return _('This category of payments has been disabled.'), None
447        payment = createObject(u'waeup.StudentOnlinePayment')
448        timestamp = ("%d" % int(time()*10000))[1:]
449        payment.p_id = "p%s" % timestamp
450        payment.p_category = category
451        payment.p_item = p_item
452        payment.p_session = p_session
453        payment.p_level = p_level
454        payment.p_current = p_current
455        payment.amount_auth = amount
456        return None, payment
457
458    def warnCreditsOOR(self, studylevel, course=None):
459        studycourse = studylevel.__parent__
460        certificate = getattr(studycourse,'certificate', None)
461        current_level = studycourse.current_level
462        if None in (current_level, certificate):
463            return
464        end_level = certificate.end_level
465        if studylevel.student.faccode in (
466            'MED', 'DEN', 'BMS') and studylevel.level == 200:
467            limit = 61
468        elif current_level >= end_level:
469            limit = 51
470        else:
471            limit = 50
472        if course and studylevel.total_credits + course.credits > limit:
473            return _('Maximum credits exceeded.')
474        elif studylevel.total_credits > limit:
475            return _('Maximum credits exceeded.')
476        return
477
478    def clearance_disabled_message(self, student):
479        if student.is_postgrad:
480            return None
481        try:
482            session_config = grok.getSite()[
483                'configuration'][str(student.current_session)]
484        except KeyError:
485            return _('Session configuration object is not available.')
486        if not session_config.clearance_enabled:
487            return _('Clearance is disabled for this session.')
488        return None
489
490    def renderPDFTranscript(self, view, filename='transcript.pdf',
491                  student=None,
492                  studentview=None,
493                  note=None,
494                  signatures=(),
495                  sigs_in_footer=(),
496                  digital_sigs=(),
497                  show_scans=True, topMargin=1.5,
498                  omit_fields=(),
499                  tableheader=None,
500                  no_passport=False,
501                  save_file=False):
502        """Render pdf slip of a transcripts.
503        """
504        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
505        # XXX: tell what the different parameters mean
506        style = getSampleStyleSheet()
507        creator = self.getPDFCreator(student)
508        data = []
509        doc_title = view.label
510        author = '%s (%s)' % (view.request.principal.title,
511                              view.request.principal.id)
512        footer_text = view.label.split('\n')
513        if len(footer_text) > 2:
514            # We can add a department in first line
515            footer_text = footer_text[1]
516        else:
517            # Only the first line is used for the footer
518            footer_text = footer_text[0]
519        if getattr(student, 'student_id', None) is not None:
520            footer_text = "%s - %s - " % (student.student_id, footer_text)
521
522        # Insert student data table
523        if student is not None:
524            #bd_translation = trans(_('Base Data'), portal_language)
525            #data.append(Paragraph(bd_translation, HEADING_STYLE))
526            data.append(render_student_data(
527                studentview, view.context,
528                omit_fields, lang=portal_language,
529                slipname=filename,
530                no_passport=no_passport))
531
532        transcript_data = view.context.getTranscriptData()
533        levels_data = transcript_data[0]
534
535        contextdata = []
536        f_label = trans(_('Course of Study:'), portal_language)
537        f_label = Paragraph(f_label, ENTRY1_STYLE)
538        f_text = formatted_text(view.context.certificate.longtitle)
539        f_text = Paragraph(f_text, ENTRY1_STYLE)
540        contextdata.append([f_label,f_text])
541
542        f_label = trans(_('Faculty:'), portal_language)
543        f_label = Paragraph(f_label, ENTRY1_STYLE)
544        f_text = formatted_text(
545            view.context.certificate.__parent__.__parent__.__parent__.longtitle)
546        f_text = Paragraph(f_text, ENTRY1_STYLE)
547        contextdata.append([f_label,f_text])
548
549        f_label = trans(_('Department:'), portal_language)
550        f_label = Paragraph(f_label, ENTRY1_STYLE)
551        f_text = formatted_text(
552            view.context.certificate.__parent__.__parent__.longtitle)
553        f_text = Paragraph(f_text, ENTRY1_STYLE)
554        contextdata.append([f_label,f_text])
555
556        f_label = trans(_('Entry Session:'), portal_language)
557        f_label = Paragraph(f_label, ENTRY1_STYLE)
558        f_text = formatted_text(
559            view.session_dict.get(view.context.entry_session))
560        f_text = Paragraph(f_text, ENTRY1_STYLE)
561        contextdata.append([f_label,f_text])
562
563        f_label = trans(_('Final Session:'), portal_language)
564        f_label = Paragraph(f_label, ENTRY1_STYLE)
565        f_text = formatted_text(
566            view.session_dict.get(view.context.current_session))
567        f_text = Paragraph(f_text, ENTRY1_STYLE)
568        contextdata.append([f_label,f_text])
569
570        f_label = trans(_('Entry Mode:'), portal_language)
571        f_label = Paragraph(f_label, ENTRY1_STYLE)
572        f_text = formatted_text(view.studymode_dict.get(
573            view.context.entry_mode))
574        f_text = Paragraph(f_text, ENTRY1_STYLE)
575        contextdata.append([f_label,f_text])
576
577        f_label = trans(_('Final Verdict:'), portal_language)
578        f_label = Paragraph(f_label, ENTRY1_STYLE)
579        f_text = formatted_text(view.studymode_dict.get(
580            view.context.current_verdict))
581        f_text = Paragraph(f_text, ENTRY1_STYLE)
582        contextdata.append([f_label,f_text])
583
584        f_label = trans(_('Cumulative GPA:'), portal_language)
585        f_label = Paragraph(f_label, ENTRY1_STYLE)
586        format_float = getUtility(IKofaUtils).format_float
587        cgpa = format_float(transcript_data[1], 3)
588        if student.state == GRADUATED:
589            f_text = formatted_text('%s (%s)' % (
590                cgpa, self.getClassFromCGPA(transcript_data[1], student)[1]))
591        else:
592            f_text = formatted_text('%s' % cgpa)
593        f_text = Paragraph(f_text, ENTRY1_STYLE)
594        contextdata.append([f_label,f_text])
595
596        contexttable = Table(contextdata,style=SLIP_STYLE)
597        data.append(contexttable)
598
599        transcripttables = render_transcript_data(
600            view, tableheader, levels_data, lang=portal_language)
601        data.extend(transcripttables)
602
603        # Insert signatures
604        # XXX: We are using only sigs_in_footer in waeup.kofa, so we
605        # do not have a test for the following lines.
606        if signatures and not sigs_in_footer:
607            data.append(Spacer(1, 20))
608            # Render one signature table per signature to
609            # get date and signature in line.
610            for signature in signatures:
611                signaturetables = get_signature_tables(signature)
612                data.append(signaturetables[0])
613
614        # Insert digital signatures
615        if digital_sigs:
616            data.append(Spacer(1, 20))
617            sigs = digital_sigs.split('\n')
618            for sig in sigs:
619                data.append(Paragraph(sig, NOTE_STYLE))
620
621        view.response.setHeader(
622            'Content-Type', 'application/pdf')
623        try:
624            pdf_stream = creator.create_pdf(
625                data, None, doc_title, author=author, footer=footer_text,
626                note=note, sigs_in_footer=sigs_in_footer, topMargin=topMargin)
627        except IOError:
628            view.flash(_('Error in image file.'))
629            return view.redirect(view.url(view.context))
630        if save_file:
631            self._saveTranscriptPDF(student, pdf_stream)
632            return
633        return pdf_stream
634
635    #: A tuple containing the names of registration states in which changing of
636    #: passport pictures is allowed.
637    PORTRAIT_CHANGE_STATES = (ADMITTED, CLEARANCE,)
638
639    # Uniben prefix
640    STUDENT_ID_PREFIX = u'B'
641
642    STUDENT_EXPORTER_NAMES = (
643            'students',
644            'studentstudycourses',
645            'studentstudylevels',
646            'coursetickets',
647            'studentpayments',
648            'bedtickets',
649            'trimmed',
650            'outstandingcourses',
651            'unpaidpayments',
652            'sfpaymentsoverview',
653            'sessionpaymentsoverview',
654            'studylevelsoverview',
655            'combocard',
656            'bursary',
657            'accommodationpayments',
658            'transcriptdata',
659            'trimmedpayments',
660            )
Note: See TracBrowser for help on using the repository browser.