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

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

Customize warnCourseAlreadyPassed.

  • Property svn:keywords set to Id
File size: 29.7 KB
Line 
1## $Id: utils.py 16406 2021-03-05 15:59:19Z 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 == 'medical_quest':
278            amount = academic_session.medical_quest_fee
279        elif category.startswith('pharmd') \
280            and student.current_mode == 'special_ft':
281            amount = 80000.0
282        #elif category == 'develop' and student.is_postgrad:
283        #    amount = academic_session.development_fee
284        elif category == 'bed_allocation':
285            p_item = self.getAccommodationDetails(student)['bt']
286            desired_hostel = student['accommodation'].desired_hostel
287            if not desired_hostel:
288                return _(u'Select your favoured hostel first.'), None
289            if desired_hostel and desired_hostel != 'no':
290                p_item = u'%s (%s)' % (p_item, desired_hostel)
291            amount = academic_session.booking_fee
292            if student.is_postgrad:
293                amount += 500
294        elif category == 'hostel_maintenance':
295            amount = 0.0
296            bedticket = student['accommodation'].get(
297                str(student.current_session), None)
298            if bedticket is not None and bedticket.bed is not None:
299                p_item = bedticket.bed_coordinates
300                if bedticket.bed.__parent__.maint_fee > 0:
301                    amount = bedticket.bed.__parent__.maint_fee
302                else:
303                    # fallback
304                    amount = academic_session.maint_fee
305            else:
306                return _(u'No bed allocated.'), None
307        #elif category == 'hostel_application':
308        #    amount = 1000.0
309        #elif category.startswith('tempmaint'):
310        #    if not self._hostelApplicationPaymentMade(
311        #        student, student.current_session):
312        #        return _(
313        #            'You have not yet paid the hostel application fee.'), None
314        #    if category == 'tempmaint_1':
315        #        amount = 8150.0
316        #    elif category == 'tempmaint_2':
317        #        amount = 12650.0
318        #    elif category == 'tempmaint_3':
319        #        amount = 9650.0
320        elif category == 'clearance':
321            p_item = student.certcode
322            if p_item is None:
323                return _('Study course data are incomplete.'), None
324            if student.is_jupeb:
325                amount = 50000.0
326            elif student.faccode.startswith('FCETA'):
327                # ASABA and AKOKA
328                amount = 35000.0
329            elif student.faccode in ('BMS', 'MED', 'DEN'):
330            #elif p_item in ('BSCANA', 'BSCMBC', 'BMLS', 'BSCNUR', 'BSCPHS', 'BDS',
331            #    'MBBSMED', 'MBBSNDU', 'BSCPTY', 'BSCPST'):
332                amount = 80000.0
333            elif student.faccode == 'DCOEM':
334                return _('Acceptance fee payment not necessary.'), None
335            else:
336                amount = 60000.0
337        elif category == 'schoolfee':
338            try:
339                certificate = student['studycourse'].certificate
340                p_item = certificate.code
341            except (AttributeError, TypeError):
342                return _('Study course data are incomplete.'), None
343            if previous_session:
344                # Students can pay for previous sessions in all workflow states.
345                # Fresh students are excluded by the update method of the
346                # PreviousPaymentAddFormPage.
347                if previous_session == student['studycourse'].entry_session:
348                    if student.is_foreigner:
349                        amount = getattr(certificate, 'school_fee_3', 0.0)
350                    else:
351                        amount = getattr(certificate, 'school_fee_1', 0.0)
352                else:
353                    if student.is_foreigner:
354                        amount = getattr(certificate, 'school_fee_4', 0.0)
355                    else:
356                        amount = getattr(certificate, 'school_fee_2', 0.0)
357                        # Old returning students might get a discount.
358                        if student.entry_session < 2017 \
359                            and certificate.custom_float_1:
360                            amount -= certificate.custom_float_1
361            else:
362                if student.state == CLEARED:
363                    if student.is_foreigner:
364                        amount = getattr(certificate, 'school_fee_3', 0.0)
365                    else:
366                        amount = getattr(certificate, 'school_fee_1', 0.0)
367                elif student.state == PAID and student.is_postgrad:
368                    p_session += 1
369                    academic_session = self._getSessionConfiguration(p_session)
370                    if academic_session == None:
371                        return _(u'Session configuration object is not available.'), None
372
373                    # Students are only allowed to pay for the next session
374                    # if current session payment
375                    # has really been made, i.e. payment object exists.
376                    #if not self._paymentMade(
377                    #    student, student.current_session):
378                    #    return _('You have not yet paid your current/active' +
379                    #             ' session. Please use the previous session' +
380                    #             ' payment form first.'), None
381
382                    if student.is_foreigner:
383                        amount = getattr(certificate, 'school_fee_4', 0.0)
384                    else:
385                        amount = getattr(certificate, 'school_fee_2', 0.0)
386                elif student.state == RETURNING:
387                    # In case of returning school fee payment the payment session
388                    # and level contain the values of the session the student
389                    # has paid for.
390                    p_session, p_level = self.getReturningData(student)
391                    academic_session = self._getSessionConfiguration(p_session)
392                    if academic_session == None:
393                        return _(u'Session configuration object is not available.'), None
394
395                    # Students are only allowed to pay for the next session
396                    # if current session payment has really been made,
397                    # i.e. payment object exists and is paid.
398                    #if not self._paymentMade(
399                    #    student, student.current_session):
400                    #    return _('You have not yet paid your current/active' +
401                    #             ' session. Please use the previous session' +
402                    #             ' payment form first.'), None
403
404                    if student.is_foreigner:
405                        amount = getattr(certificate, 'school_fee_4', 0.0)
406                    else:
407                        amount = getattr(certificate, 'school_fee_2', 0.0)
408                        # Old returning students might get a discount.
409                        if student.entry_session < 2017 \
410                            and certificate.custom_float_1:
411                            amount -= certificate.custom_float_1
412                # PHARMD school fee amount is fixed and previously paid
413                # installments in current session are deducted.
414                if student.current_mode == 'special_ft' \
415                    and student.state in (RETURNING, CLEARED):
416                    if student.is_foreigner:
417                        amount = 260000.0 - self._pharmdInstallments(student)
418                    else:
419                        amount = 160000.0 - self._pharmdInstallments(student)
420            # Give 50% school fee discount to staff members.
421            if student.is_staff:
422                amount /= 2
423        if amount in (0.0, None):
424            return _('Amount could not be determined.'), None
425        # Add session specific penalty fee.
426        if category == 'schoolfee' and student.is_postgrad:
427            amount += academic_session.penalty_pg
428            amount += academic_session.development_fee
429        elif category == 'schoolfee' and student.current_mode == ('ug_ft'):
430            amount += academic_session.penalty_ug_ft
431        elif category == 'schoolfee' and student.current_mode == ('ug_pt'):
432            amount += academic_session.penalty_ug_pt
433        elif category == 'schoolfee' and student.current_mode == ('ug_sw'):
434            amount += academic_session.penalty_sw
435        elif category == 'schoolfee' and student.current_mode in (
436            'dp_ft', 'dp_pt'):
437            amount += academic_session.penalty_dp
438        if category.startswith('tempmaint'):
439            p_item = getUtility(IKofaUtils).PAYMENT_CATEGORIES[category]
440            p_item = unicode(p_item)
441            # Now we change the category because tempmaint payments
442            # will be obsolete when Uniben returns to Kofa bed allocation.
443            category = 'hostel_maintenance'
444        # Create ticket.
445        if self.samePaymentMade(student, category, p_item, p_session):
446            return _('This type of payment has already been made.'), None
447        if self._isPaymentDisabled(p_session, category, student):
448            return _('This category of payments has been disabled.'), None
449        payment = createObject(u'waeup.StudentOnlinePayment')
450        timestamp = ("%d" % int(time()*10000))[1:]
451        payment.p_id = "p%s" % timestamp
452        payment.p_category = category
453        payment.p_item = p_item
454        payment.p_session = p_session
455        payment.p_level = p_level
456        payment.p_current = p_current
457        payment.amount_auth = amount
458        return None, payment
459
460    def warnCreditsOOR(self, studylevel, course=None):
461        studycourse = studylevel.__parent__
462        certificate = getattr(studycourse,'certificate', None)
463        current_level = studycourse.current_level
464        if None in (current_level, certificate):
465            return
466        end_level = certificate.end_level
467        if studylevel.student.faccode in (
468            'MED', 'DEN', 'BMS') and studylevel.level == 200:
469            limit = 61
470        elif current_level >= end_level:
471            limit = 51
472        else:
473            limit = 50
474        if course and studylevel.total_credits + course.credits > limit:
475            return _('Maximum credits exceeded.')
476        elif studylevel.total_credits > limit:
477            return _('Maximum credits exceeded.')
478        return
479
480    def warnCourseAlreadyPassed(self, studylevel, course):
481        """Return message if course has already been passed at
482        previous levels.
483        """
484        previous_verdict = studylevel.__parent__.previous_verdict
485        if previous_verdict in ('C', 'M'):
486            return False
487        for slevel in studylevel.__parent__.values():
488            for cticket in slevel.values():
489                if cticket.code == course.code \
490                    and cticket.total_score >= cticket.passmark:
491                    return _('Course has already been passed at previous level.')
492        return False
493
494    def clearance_disabled_message(self, student):
495        if student.is_postgrad:
496            return None
497        try:
498            session_config = grok.getSite()[
499                'configuration'][str(student.current_session)]
500        except KeyError:
501            return _('Session configuration object is not available.')
502        if not session_config.clearance_enabled:
503            return _('Clearance is disabled for this session.')
504        return None
505
506    def renderPDFTranscript(self, view, filename='transcript.pdf',
507                  student=None,
508                  studentview=None,
509                  note=None,
510                  signatures=(),
511                  sigs_in_footer=(),
512                  digital_sigs=(),
513                  show_scans=True, topMargin=1.5,
514                  omit_fields=(),
515                  tableheader=None,
516                  no_passport=False,
517                  save_file=False):
518        """Render pdf slip of a transcripts.
519        """
520        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
521        # XXX: tell what the different parameters mean
522        style = getSampleStyleSheet()
523        creator = self.getPDFCreator(student)
524        data = []
525        doc_title = view.label
526        author = '%s (%s)' % (view.request.principal.title,
527                              view.request.principal.id)
528        footer_text = view.label.split('\n')
529        if len(footer_text) > 2:
530            # We can add a department in first line
531            footer_text = footer_text[1]
532        else:
533            # Only the first line is used for the footer
534            footer_text = footer_text[0]
535        if getattr(student, 'student_id', None) is not None:
536            footer_text = "%s - %s - " % (student.student_id, footer_text)
537
538        # Insert student data table
539        if student is not None:
540            #bd_translation = trans(_('Base Data'), portal_language)
541            #data.append(Paragraph(bd_translation, HEADING_STYLE))
542            data.append(render_student_data(
543                studentview, view.context,
544                omit_fields, lang=portal_language,
545                slipname=filename,
546                no_passport=no_passport))
547
548        transcript_data = view.context.getTranscriptData()
549        levels_data = transcript_data[0]
550
551        contextdata = []
552        f_label = trans(_('Course of Study:'), portal_language)
553        f_label = Paragraph(f_label, ENTRY1_STYLE)
554        f_text = formatted_text(view.context.certificate.longtitle)
555        f_text = Paragraph(f_text, ENTRY1_STYLE)
556        contextdata.append([f_label,f_text])
557
558        f_label = trans(_('Faculty:'), portal_language)
559        f_label = Paragraph(f_label, ENTRY1_STYLE)
560        f_text = formatted_text(
561            view.context.certificate.__parent__.__parent__.__parent__.longtitle)
562        f_text = Paragraph(f_text, ENTRY1_STYLE)
563        contextdata.append([f_label,f_text])
564
565        f_label = trans(_('Department:'), portal_language)
566        f_label = Paragraph(f_label, ENTRY1_STYLE)
567        f_text = formatted_text(
568            view.context.certificate.__parent__.__parent__.longtitle)
569        f_text = Paragraph(f_text, ENTRY1_STYLE)
570        contextdata.append([f_label,f_text])
571
572        f_label = trans(_('Entry Session:'), portal_language)
573        f_label = Paragraph(f_label, ENTRY1_STYLE)
574        f_text = formatted_text(
575            view.session_dict.get(view.context.entry_session))
576        f_text = Paragraph(f_text, ENTRY1_STYLE)
577        contextdata.append([f_label,f_text])
578
579        f_label = trans(_('Final Session:'), portal_language)
580        f_label = Paragraph(f_label, ENTRY1_STYLE)
581        f_text = formatted_text(
582            view.session_dict.get(view.context.current_session))
583        f_text = Paragraph(f_text, ENTRY1_STYLE)
584        contextdata.append([f_label,f_text])
585
586        f_label = trans(_('Entry Mode:'), portal_language)
587        f_label = Paragraph(f_label, ENTRY1_STYLE)
588        f_text = formatted_text(view.studymode_dict.get(
589            view.context.entry_mode))
590        f_text = Paragraph(f_text, ENTRY1_STYLE)
591        contextdata.append([f_label,f_text])
592
593        f_label = trans(_('Final Verdict:'), portal_language)
594        f_label = Paragraph(f_label, ENTRY1_STYLE)
595        f_text = formatted_text(view.studymode_dict.get(
596            view.context.current_verdict))
597        f_text = Paragraph(f_text, ENTRY1_STYLE)
598        contextdata.append([f_label,f_text])
599
600        f_label = trans(_('Cumulative GPA:'), portal_language)
601        f_label = Paragraph(f_label, ENTRY1_STYLE)
602        format_float = getUtility(IKofaUtils).format_float
603        cgpa = format_float(transcript_data[1], 3)
604        if student.state == GRADUATED:
605            f_text = formatted_text('%s (%s)' % (
606                cgpa, self.getClassFromCGPA(transcript_data[1], student)[1]))
607        else:
608            f_text = formatted_text('%s' % cgpa)
609        f_text = Paragraph(f_text, ENTRY1_STYLE)
610        contextdata.append([f_label,f_text])
611
612        contexttable = Table(contextdata,style=SLIP_STYLE)
613        data.append(contexttable)
614
615        transcripttables = render_transcript_data(
616            view, tableheader, levels_data, lang=portal_language)
617        data.extend(transcripttables)
618
619        # Insert signatures
620        # XXX: We are using only sigs_in_footer in waeup.kofa, so we
621        # do not have a test for the following lines.
622        if signatures and not sigs_in_footer:
623            data.append(Spacer(1, 20))
624            # Render one signature table per signature to
625            # get date and signature in line.
626            for signature in signatures:
627                signaturetables = get_signature_tables(signature)
628                data.append(signaturetables[0])
629
630        # Insert digital signatures
631        if digital_sigs:
632            data.append(Spacer(1, 20))
633            sigs = digital_sigs.split('\n')
634            for sig in sigs:
635                data.append(Paragraph(sig, NOTE_STYLE))
636
637        view.response.setHeader(
638            'Content-Type', 'application/pdf')
639        try:
640            pdf_stream = creator.create_pdf(
641                data, None, doc_title, author=author, footer=footer_text,
642                note=note, sigs_in_footer=sigs_in_footer, topMargin=topMargin)
643        except IOError:
644            view.flash(_('Error in image file.'))
645            return view.redirect(view.url(view.context))
646        if save_file:
647            self._saveTranscriptPDF(student, pdf_stream)
648            return
649        return pdf_stream
650
651    #: A tuple containing the names of registration states in which changing of
652    #: passport pictures is allowed.
653    PORTRAIT_CHANGE_STATES = (ADMITTED, CLEARANCE,)
654
655    # Uniben prefix
656    STUDENT_ID_PREFIX = u'B'
657
658    STUDENT_EXPORTER_NAMES = (
659            'students',
660            'studentstudycourses',
661            'studentstudylevels',
662            'coursetickets',
663            'studentpayments',
664            'bedtickets',
665            'trimmed',
666            'outstandingcourses',
667            'unpaidpayments',
668            'sfpaymentsoverview',
669            'sessionpaymentsoverview',
670            'studylevelsoverview',
671            'combocard',
672            'bursary',
673            'accommodationpayments',
674            'transcriptdata',
675            'trimmedpayments',
676            'medicalhistory',
677            )
Note: See TracBrowser for help on using the repository browser.