Ignore:
Timestamp:
10 Sep 2012, 11:05:07 (12 years ago)
Author:
uli
Message:

Merge changes from trunk, r8786-HEAD

Location:
main/waeup.kofa/branches/uli-async-update
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/branches/uli-async-update

  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/utils.py

    r8708 r9169  
    1919"""
    2020import grok
    21 from random import SystemRandom as r
    2221from time import time
    23 from datetime import datetime
    24 from zope.i18n import translate
    25 from zope.component import getUtility, createObject
    26 from reportlab.pdfgen import canvas
    2722from reportlab.lib import colors
    2823from reportlab.lib.units import cm
    29 from reportlab.lib.enums import TA_RIGHT
    3024from reportlab.lib.pagesizes import A4
    31 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    32 from reportlab.platypus import (Frame, Paragraph, Image, PageBreak, Table,
    33                                 Spacer)
    34 from reportlab.platypus.tables import TableStyle
    35 from reportlab.platypus.flowables import PageBreak
    36 from zope.component import getUtility
     25from reportlab.lib.styles import getSampleStyleSheet
     26from reportlab.platypus import Paragraph, Image, Table, Spacer
     27from zope.component import getUtility, createObject
    3728from zope.formlib.form import setUpEditWidgets
    38 
     29from zope.i18n import translate
    3930from waeup.kofa.interfaces import (
    4031    IExtFileStore, IKofaUtils, RETURNING, PAID, CLEARED)
    4132from waeup.kofa.interfaces import MessageFactory as _
    4233from waeup.kofa.students.interfaces import IStudentsUtils
    43 from waeup.kofa.utils.helpers import now
    4434
    4535SLIP_STYLE = [
     
    127117    #data.append([Spacer(1, 12)])
    128118    portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     119
     120    f_label = formatted_label(size=12) % _('Name')
     121    f_label = Paragraph(f_label, style["Normal"])
     122    f_text = formatted_text(studentview.context.display_fullname, size=12)
     123    f_text = Paragraph(f_text, style["Normal"])
     124    data_right.append([f_label,f_text])
     125
    129126    for widget in studentview.widgets:
    130         if widget.name == 'form.adm_code':
     127        if 'name' in widget.name:
    131128            continue
    132129        f_label = formatted_label(size=12) % translate(
     
    137134        f_text = Paragraph(f_text, style["Normal"])
    138135        data_right.append([f_label,f_text])
     136
     137    if hasattr(studentview.context, 'certcode'):
     138        f_label = formatted_label(size=12) % _('Study Course')
     139        f_label = Paragraph(f_label, style["Normal"])
     140        f_text = formatted_text(studentview.context.certcode, size=12)
     141        f_text = Paragraph(f_text, style["Normal"])
     142        data_right.append([f_label,f_text])
     143
    139144    table_left = Table(data_left,style=SLIP_STYLE)
    140145    table_right = Table(data_right,style=SLIP_STYLE, colWidths=[5*cm, 6*cm])
     
    165170    return table
    166171
     172def get_signature_table(signatures, lang='en'):
     173    """Return a reportlab table containing signature fields (with date).
     174    """
     175    style = getSampleStyleSheet()
     176    space_width = 0.4  # width in cm of space between signatures
     177    table_width = 16.0 # supposed width of signature table in cms
     178    # width of signature cells in cm...
     179    sig_col_width = table_width - ((len(signatures) - 1) * space_width)
     180    sig_col_width = sig_col_width / len(signatures)
     181    data = []
     182    col_widths = [] # widths of columns
     183
     184    sig_style = [
     185        ('VALIGN',(0,-1),(-1,-1),'TOP'),
     186        ('FONT', (0,0), (-1,-1), 'Helvetica-BoldOblique', 12),
     187        ('BOTTOMPADDING', (0,0), (-1,0), 36),
     188        ('TOPPADDING', (0,-1), (-1,-1), 0),
     189        ]
     190    for num, elem in enumerate(signatures):
     191        # draw a line above each signature cell (not: empty cells in between)
     192        sig_style.append(
     193            ('LINEABOVE', (num*2,-1), (num*2, -1), 1, colors.black))
     194
     195    row = []
     196    for signature in signatures:
     197        row.append(trans(_('Date:'), lang))
     198        row.append('')
     199        if len(signatures) > 1:
     200            col_widths.extend([sig_col_width*cm, space_width*cm])
     201        else:
     202            col_widths.extend([sig_col_width/2*cm, sig_col_width/2*cm])
     203            row.append('') # empty spaceholder on right
     204    data.append(row[:-1])
     205    data.extend(([''],)*3) # insert 3 empty rows...
     206    row = []
     207    for signature in signatures:
     208        row.append(Paragraph(trans(signature, lang), style["Normal"]))
     209        row.append('')
     210    data.append(row[:-1])
     211    table = Table(data, style=sig_style, repeatRows=len(data),
     212                  colWidths=col_widths)
     213    return table
     214
    167215def docs_as_flowables(view, lang='en'):
    168216    """Create reportlab flowables out of scanned docs.
     
    190238            if img_path is None:
    191239                pass
    192             elif not img_path.endswith('.jpg'):
     240            elif not img_path[-4:] in ('.jpg', '.JPG'):
    193241                # reportlab requires jpg images, I think.
    194                 f_text = Paragraph('%s (Not displayable)' % (
     242                f_text = Paragraph('%s (not displayable)' % (
    195243                    viewlet.title,), ENTRY1_STYLE)
    196244            else:
     
    202250    return data
    203251
    204 def insert_footer(pdf,width,style,text=None, number_of_pages=1):
    205       """Render the whole footer frame.
    206       """
    207       story = []
    208       frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
    209       tz = getUtility(IKofaUtils).tzinfo
    210       timestamp = now(tz).strftime("%d/%m/%Y %H:%M:%S %Z")
    211       left_text = '<font size=10>%s</font>' % timestamp
    212       story.append(Paragraph(left_text, style["Normal"]))
    213       frame_footer.addFromList(story,pdf)
    214       story = []
    215       frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
    216       portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
    217       right_text = translate(_('<font size=10>${a} Page ${b} of ${c}</font>',
    218           mapping = {'a':text, 'b':pdf.getPageNumber(), 'c':number_of_pages}),
    219           'waeup.kofa', target_language=portal_language)
    220       story.append(Paragraph(right_text, style["Right"]))
    221       frame_footer.addFromList(story,pdf)
    222 
    223252class StudentsUtils(grok.GlobalUtility):
    224253    """A collection of methods subject to customization.
     
    227256
    228257    def getReturningData(self, student):
    229         """ This method defines what happens after school fee payment
     258        """ Define what happens after school fee payment
    230259        depending on the student's senate verdict.
    231260
     
    238267
    239268    def setReturningData(self, student):
    240         """ This method defines what happens after school fee payment
    241         depending on the student's senate verdict. It folllows
    242         the same algorithm as getReturningData but it also sets the new
    243         values
    244 
    245         In the base configuration current level is always increased
    246         by 100 no matter which verdict has been assigned.
     269        """ Define what happens after school fee payment
     270        depending on the student's senate verdict.
     271
     272        This method folllows the same algorithm as getReturningData but
     273        it also sets the new values.
    247274        """
    248275        new_session, new_level = self.getReturningData(student)
     
    250277        student['studycourse'].current_session = new_session
    251278        verdict = student['studycourse'].current_verdict
    252         student['studycourse'].current_verdict = 'NY'
     279        student['studycourse'].current_verdict = '0'
    253280        student['studycourse'].previous_verdict = verdict
    254281        return
    255282
    256     def setPaymentDetails(self, category, student):
     283    def setPaymentDetails(self, category, student,
     284            previous_session, previous_level):
    257285        """Create Payment object and set the payment data of a student for
    258286        the payment category specified.
    259287
    260288        """
    261         details = {}
    262289        p_item = u''
    263290        amount = 0.0
    264         error = u''
    265         p_session = student['studycourse'].current_session
    266         p_level = student['studycourse'].current_level
     291        if previous_session:
     292            p_session = previous_session
     293            p_level = previous_level
     294            p_current = False
     295        else:
     296            p_session = student['studycourse'].current_session
     297            p_level = student['studycourse'].current_level
     298            p_current = True
    267299        session = str(p_session)
    268300        try:
     
    276308            except (AttributeError, TypeError):
    277309                return _('Study course data are incomplete.'), None
    278             if student.state == CLEARED:
    279                 amount = getattr(certificate, 'school_fee_1', 0.0)
    280             elif student.state == RETURNING:
    281                 # In case of returning school fee payment the payment session
    282                 # and level contain the values of the session the student
    283                 # has paid for.
    284                 p_session, p_level = self.getReturningData(student)
    285                 amount = getattr(certificate, 'school_fee_2', 0.0)
    286             elif student.is_postgrad and student.state == PAID:
    287                 # Returning postgraduate students also pay for the next session
    288                 # but their level always remains the same.
    289                 p_session += 1
    290                 amount = getattr(certificate, 'school_fee_2', 0.0)
     310            if previous_session:
     311                if previous_level == 100:
     312                    amount = getattr(certificate, 'school_fee_1', 0.0)
     313                else:
     314                    amount = getattr(certificate, 'school_fee_2', 0.0)
     315            else:
     316                if student.state == CLEARED:
     317                    amount = getattr(certificate, 'school_fee_1', 0.0)
     318                elif student.state == RETURNING:
     319                    # In case of returning school fee payment the payment session
     320                    # and level contain the values of the session the student
     321                    # has paid for.
     322                    p_session, p_level = self.getReturningData(student)
     323                    amount = getattr(certificate, 'school_fee_2', 0.0)
     324                elif student.is_postgrad and student.state == PAID:
     325                    # Returning postgraduate students also pay for the next session
     326                    # but their level always remains the same.
     327                    p_session += 1
     328                    amount = getattr(certificate, 'school_fee_2', 0.0)
    291329        elif category == 'clearance':
    292330            p_item = student['studycourse'].certificate.code
     
    296334            amount = academic_session.booking_fee
    297335        if amount in (0.0, None):
    298             return _(u'Amount could not be determined.'), None
     336            return _('Amount could not be determined.' +
     337                     ' Would you like to pay for a previous session?'), None
    299338        for key in student['payments'].keys():
    300339            ticket = student['payments'][key]
     
    303342               ticket.p_item == p_item and \
    304343               ticket.p_session == p_session:
    305                   return _('This type of payment has already been made.'), None
     344                  return _('This type of payment has already been made.' +
     345                           ' Would you like to pay for a previous session?'), None
    306346        payment = createObject(u'waeup.StudentOnlinePayment')
    307         timestamp = "%d" % int(time()*1000)
     347        timestamp = ("%d" % int(time()*10000))[1:]
    308348        payment.p_id = "p%s" % timestamp
    309349        payment.p_category = category
     
    311351        payment.p_session = p_session
    312352        payment.p_level = p_level
     353        payment.p_current = p_current
    313354        payment.amount_auth = amount
    314355        return None, payment
     
    333374            return
    334375        end_level = certificate.end_level
    335         if entry_session == grok.getSite()['hostels'].accommodation_session:
     376        if current_level == 10:
     377            bt = 'pr'
     378        elif entry_session == grok.getSite()['hostels'].accommodation_session:
    336379            bt = 'fr'
    337380        elif current_level >= end_level:
     
    357400    def renderPDF(self, view, filename='slip.pdf', student=None,
    358401                  studentview=None, tableheader=None, tabledata=None,
    359                   note=None):
     402                  note=None, signatures=None):
    360403        """Render pdf slips for various pages.
    361404        """
     
    373416            footer_text = "%s - %s - " % (student.student_id, footer_text)
    374417
     418        # Insert history
     419        if not filename.startswith('payment'):
     420            data.extend(creator.fromStringList(student.history.messages))
     421
    375422        # Insert student data table
    376423        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     
    399446            contenttable = render_table_data(tableheader,tabledata)
    400447            data.append(contenttable)
     448
     449        # Insert signatures
     450        if signatures:
     451            data.append(Spacer(1, 20))
     452            signaturetable = get_signature_table(signatures)
     453            data.append(signaturetable)
    401454
    402455        view.response.setHeader(
     
    412465
    413466    VERDICTS_DICT = {
    414         'NY': _('(not yet)'),
     467        '0': _('(not yet)'),
    415468        'A': 'Successful student',
    416469        'B': 'Student with carryover courses',
Note: See TracChangeset for help on using the changeset viewer.