Index: main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10556)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10557)
@@ -65,2 +65,86 @@
         table.append(line)
     return table
+
+from reportlab.lib import colors
+from reportlab.lib.styles import getSampleStyleSheet
+from reportlab.lib.units import cm
+from reportlab.platypus import Paragraph, Table, Spacer
+from reportlab.lib.pagesizes import A4, landscape
+from waeup.kofa.reports import IReport, IReportGenerator
+from waeup.kofa.reports import Report
+from waeup.kofa.browser.interfaces import IPDFCreator
+from waeup.kofa.university.vocabularies import course_levels
+
+STYLE = getSampleStyleSheet()
+
+def tbl_data_to_table(data):
+    result = []
+    new_col_names = ('Student Id', _('Matric No.'), _('Name') ,
+                     _('Total Credits'), _('Total Credits Passed'),
+                     _('GPA'), _('Courses Failed'))
+    table = [new_col_names]
+    for line in data:
+        table.append(line)
+    return table
+
+TABLE_STYLE = [
+    ('FONT', (0,0), (-1,-1), 'Helvetica', 8),
+    ('FONT', (0,0), (0,-1), 'Helvetica-Bold', 8),
+    ('FONT', (0,0), (-1,0), 'Helvetica-Bold', 8),
+    ('FONT', (0,-1), (-1,-1), 'Helvetica-Bold', 8),
+    ('FONT', (-1,0), (-1,-1), 'Helvetica-Bold', 8),
+    ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
+    ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
+    ('LINEBELOW', (0,-1), (-1,-1), 0.25, colors.black),
+    ('LINEAFTER', (-1,0), (-1,-1), 0.25, colors.black),
+    ('LINEBEFORE', (-1,0), (-1,-1), 1.0, colors.black),
+    #('LINEABOVE', (0,-1), (-1,-1), 1.0, colors.black),
+    #('LINEABOVE', (0,0), (-1,0), 0.25, colors.black),
+    ('BOX', (0,0), (-1,-1), 1, colors.black),
+    ]
+
+@implementer(ILevelReport)
+class LevelReport(Report):
+    data = None
+    session = None
+    level = None
+    faccode = None
+    depcode = None
+
+    def __init__(self, faccode, depcode, session, level, author='System'):
+        super(LevelReport, self).__init__(
+            args=[faccode, depcode, session, level], kwargs={'author':author})
+        site = grok.getSite()
+        self.session = academic_sessions_vocab.getTerm(session).title
+        self.level = course_levels.getTerm(level).title
+        self.levelcode = level
+        self.sessioncode = session
+        self.faccode = faccode
+        self.depcode = depcode
+        self.factitle = site['faculties'][faccode].longtitle()
+        self.deptitle = site['faculties'][faccode][depcode].longtitle()
+        self.author = author
+        self.creation_dt_string = self.creation_dt.astimezone(
+            getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z")
+        self.data = get_students_by(faccode, depcode, session, level)
+
+    def create_pdf(self):
+        creator = getUtility(IPDFCreator)
+        table_data = tbl_data_to_table(self.data)
+        #col_widths = [3.5*cm] * len(self.data[0])
+        pdf_data = [Paragraph('<b>%s</b>' % self.creation_dt_string,
+                              STYLE["Normal"]),
+                    Spacer(1, 12),]
+        pdf_data += [Paragraph('%s<br />%s<br />Level: %s<br />Session: %s' % (
+                    self.factitle, self.deptitle, self.level, self.session),
+                    STYLE["Normal"]),
+                    Spacer(1, 12),]
+        pdf_data += [
+            Table(table_data, style=TABLE_STYLE)]   #, colWidths=col_widths)]
+        doc_title = 'Level Report'
+        pdf = creator.create_pdf(
+            pdf_data, None, doc_title, self.author,
+            'Level Report %s/%s/%s/%s' % (
+            self.faccode, self.depcode, self.levelcode, self.sessioncode),
+            pagesize=landscape(A4))
+        return pdf
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py	(revision 10556)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py	(revision 10557)
@@ -5,9 +5,10 @@
 from waeup.kofa.interfaces import IJobManager
 from waeup.kofa.students.reports.level_report import (
-    get_students_by)
+    get_students_by, LevelReport)
 from waeup.kofa.students.tests.test_catalog import CatalogTestSetup
 from waeup.kofa.students.tests.test_browser import StudentsFullSetup
 from waeup.kofa.testing import FunctionalLayer
 from waeup.kofa.tests.test_async import FunctionalAsyncTestCase
+from waeup.kofa.browser.tests.test_pdf import samples_dir
 
 class LevelReportTests(CatalogTestSetup):
@@ -21,2 +22,11 @@
             [(u'K1000000', u'1234', u'Bob Tester', 30, 30, 5.0, [])])
         return
+
+    def test_create_pdf(self):
+        report = LevelReport('fac1', 'dep1', 2010, 100)
+        result = report.create_pdf()
+        self.assertTrue(result.startswith('%PDF-'))
+        path = os.path.join(samples_dir(), 'level_report.pdf')
+        open(path, 'wb').write(result)
+        print "Sample level_report.pdf written to %s" % path
+        return
